1 条题解

  • 0
    @ 2026-9-3 20:12:19

    一道基础 dp 题远古 IOI 题。

    dpi,x,ydp_{i,x,y} 表示考虑完了前 ii 位,以当前位结尾的后缀中 L 的个数减 P 的个数最大为 xxP 的个数减 L 的个数最大为 yy,剩下的位有多少种合法的构造方案,由题意得 0x,y<30\le x,y<3。直接暴力转移即可。

    花园的序号 == 字典序小于这个花园的个数 +1+1。考虑如何统计字典序小于这个花园的个数,可以枚举第一个不同的位,暴力求和即可。

    代码:

    #include<bits/stdc++.h>
    #define mxn 1000003
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define rept(i,a,b) for(int i=a;i<b;++i)
    #define drep(i,a,b) for(int i=a;i>=b;--i)
    using namespace std;
    int n,m,x,y,ans,f[mxn][3][3];
    char s[mxn];
    signed main(){
    	scanf("%d%d%s",&n,&m,s+1);
    	rept(i,0,3)rept(j,0,3)f[n][i][j]=1;
    	drep(i,n-1,1){
    		rept(x,0,3){
    			rept(y,0,3){
    				if(x!=2)f[i][x][y]=f[i+1][x+1][max(y-1,0)];
    				if(y!=2)f[i][x][y]=(f[i][x][y]+f[i+1][max(x-1,0)][y+1])%m;
    			}
    		}
    	}
    	rep(i,1,n){
    		if(s[i]=='L'){
    			x++,y=max(y-1,0);
    			if(x>2)break;
    		}else{
    			if(x!=2)ans=(ans+f[i][x+1][max(y-1,0)])%m;
    			x=max(x-1,0),y++;
    			if(y>2)break;
    		}
    	}
    	cout<<(ans+1)%m;
    	return 0;
    }
    
    • 1

    信息

    ID
    3450
    时间
    1500ms
    内存
    164MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者