1 条题解

  • 0
    @ 2026-5-7 16:49:08

    这是一道动态规划的题目。

    首先判断是否存在这个石碑,设现在需要找正好有 kk 个,长度为 nn 的石碑,则一共有 (n1k)\binom {n-1}{k} 个石碑,而所有可行的数量则为 2×i=0k(n1i)2×\sum_{i=0}^k \binom {n-1}{i} 个,设这个为 xjn,kxj_{n,k},也写为 qq,其中回文的数量,也就是前面一半和后面一半完全一样,因此就是 $xj_{\lceil{\frac{n}{2}}\rceil,\lfloor{\frac{k}{2}}\rfloor}$,设这个数量为 pp,则答案为 q+p2\frac{q+p}{2},如果 ii 大于这个,就可以直接输出超过的答案。

    然后进行动态规划,我们每一位进行筛选,设走到了第 pp 位,则先假设 ansp=Ians_p=I,然后进行动态规划求出到目前位置 ansans 序列的可行数量,没有确定或者假设的则 IIXX 都可以,然后可以从左和右同时进行,设现在是左边第 ii 位,则右边是第 ni+1n-i+1 位,如果左边和右边一样,则不确定能不能,如果左边是 II,右边是 XX,则之后一定可以,如果左边是 XX,右边是 II,而且不一定可以,则一定不可以。然后可以进行动态规划,方式见代码,设最后答案为 kk,如果 iki>k,则代表这一位是 XX,然后 ii 减去 kk,否则是 II。复杂度 O(n2k)O(n^2k)

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    long long ba[65][65],c[65][65],dp[65][65][4][2],hf;
    int main(){
    	for(long long j=0;j<=60;j++){
    		c[j][0]=1;ba[j+1][0]=1;
    		for(long long k=1;k<=j;k++){
    			c[j][k]=c[j-1][k]+c[j-1][k-1];ba[j+1][k]=c[j][k]+ba[j+1][k-1];
    		}
    	}
    	long long n,l,i;cin>>n>>l>>i;
    	if(i>ba[n][l]+ba[(n+1)/2][l/2]){
    		cout<<"NO SUCH STONE";
    	}else{
    		string s;
    		for(long long j=0;j<n;j++){
    			s+='2';
    		}
    		for(long long v=0;v<n;v++){
    			s[v]='0';long long all=0;
    			for(long long p=0;p<4;p++){
    				dp[0][0][p][0]=dp[0][0][p][1]=0;
    				if(p==2){
    					continue;
    				}
    				if(s[0]=='2' || s[0]-48==p/2){
    					if(s[n-1]=='2' || s[n-1]-48==p%2){
    						if(p==1){
    							dp[0][0][p][1]=1;
    						}else{
    							dp[0][0][p][0]=1;
    						}
    					}
    				}
    			} 
    			for(long long k=1;k<(n+1)/2;k++){
    				for(long long p=0;p<=l;p++){
    					for(long long q=0;q<4;q++){
    						dp[k][p][q][0]=dp[k][p][q][1]=0;
    						if(n%2==1 && k==(n+1)/2-1 && (q==1 || q==2)){
    							continue;
    						}
    						if(s[k]=='2' || s[k]-48==q/2){
    							if(s[n-1-k]=='2' || s[n-1-k]-48==q%2){
    								for(long long r=0;r<4;r++){
    									long long sp=abs(q/2-r/2)+abs(q%2-r%2);
    									if(n%2==0 && k==(n+1)/2-1 && (q==1 || q==2)){
    										sp++;
    									}
    									if(p<sp){
    										continue;
    									}
    									if(q==1){
    										dp[k][p][q][1]+=dp[k-1][p-sp][r][0]+dp[k-1][p-sp][r][1];
    									}else if(q==2){
    										dp[k][p][q][1]+=dp[k-1][p-sp][r][1];
    									}else{
    										dp[k][p][q][0]+=dp[k-1][p-sp][r][0];
    										dp[k][p][q][1]+=dp[k-1][p-sp][r][1];
    									}
    								}
    							}
    						}
    					}
    				}
    			}
    			for(long long k=0;k<=l;k++){
    				long long a2=0;
    				for(long long p=0;p<8;p++){
    					a2+=dp[(n+1)/2-1][k][p/2][p%2];
    				}
    				all+=a2;
    			}
    			if(i>all){
    				i-=all;cout<<'X';s[v]='1';
    			}else{
    				cout<<'I';
    			}
    		}
    	}
    }
    
    • 1

    信息

    ID
    2819
    时间
    1000ms
    内存
    32MiB
    难度
    10
    标签
    递交数
    3
    已通过
    3
    上传者