codeforces853D
Posted pandaking
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces853D相关的知识,希望对你有一定的参考价值。
题意:给出一个字符串,问它分别具有多少个k级字符串。一个回文串叫做1级回文串,一个回文串为k级回文串当且仅当它的左半部分和右半部分相同,且两部分都是(k-1)级回文串。
那么怎么判断呢,首先你可以先预处理好所有的回文串! 按照按照区间dp的顺序枚举好它的顺序,如果当前子串s【i,j】是一个回文串,那么肯定的是它的值是可以确定的是dp[i,j]=dp[i,mid-1||mid]+1,由于当前串还可以看成其他长度的串,如长度为4的串可以看成为3的串,或者可以看成长度为2的串,为1的串!
下面是ac代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 char sz[5100]; 4 int ans[5100]; 5 int dp[5100][5100],hw[5100][5100]; 6 int len; 7 int main(){ 8 scanf("%s",sz+1); 9 len=strlen(sz+1); 10 for(int i=1;i<=len;i++) hw[i][i]=1; 11 for(int i=1;i<=len;i++){ 12 for(int j=1;j<=len;j++){ 13 if(i-j<0||i+j>len) break; 14 if(sz[i-j]==sz[i+j]){ 15 hw[i-j][i+j]=1; 16 }else break; 17 } 18 for(int j=1;j<=len;j++){ 19 if(i-j+1<0||i+j>len) break; 20 if(sz[i-j+1]==sz[i+j]){ 21 hw[i-j+1][i+j]=1; 22 }else break; 23 } 24 } 25 for(int i=len;i>=1;i--){ 26 for(int j=i;j<=len;j++){ 27 if(i==j){ 28 ans[1]++; 29 dp[i][j]=1; 30 }else{ 31 int k=(i+j)/2; 32 if((j-i+1)%2==1){ 33 if(hw[i][j]==1){ 34 dp[i][j]=dp[i][k-1]+1; 35 for(int p=1;p<=dp[i][j];p++) ans[p]++; 36 } 37 }else{ 38 if(hw[i][j]==1){ 39 dp[i][j]=dp[i][k]+1; 40 for(int p=1;p<=dp[i][j];p++) ans[p]++; 41 } 42 } 43 } 44 } 45 } 46 for(int i=1;i<len;i++) printf("%d ",ans[i]); 47 printf("%d ",ans[len]); 48 return 0; 49 }
下面是原来wa了的代码,wa了的原因很简单,是因为我设置左右子串都必须是回文串,但是只要当前串是就可以了,
1 #include<bits/stdc++.h> 2 using namespace std; 3 char sz[5100]; 4 int ans[5100]; 5 int dp[5100][5100],hw[5100][5100]; 6 int len; 7 int main(){ 8 scanf("%s",sz+1); 9 len=strlen(sz+1); 10 for(int i=1;i<=len;i++) hw[i][i]=1; 11 for(int i=1;i<=len;i++){ 12 for(int j=1;j<=len;j++){ 13 if(i-j<0||i+j>len) break; 14 if(sz[i-j]==sz[i+j]){ 15 hw[i-j][i+j]=1; 16 ans[1]++; 17 }else break; 18 } 19 for(int j=1;j<=len;j++){ 20 if(i-j+1<0||i+j>len) break; 21 if(sz[i-j+1]==sz[i+j]){ 22 hw[i-j+1][i+j]=1; 23 ans[1]++; 24 }else break; 25 } 26 } 27 28 for(int i=len;i>=1;i--){ 29 for(int j=i;j<=len;j++){ 30 if(i==j){ 31 ans[1]++; 32 dp[i][j]=1; 33 }else{ 34 int k=(i+j)/2; 35 if((j-i+1)%2==1){ 36 if(hw[i][k-1]==1&&hw[k+1][j]==1&&hw[i][j]==1){ 37 dp[i][j]=max(dp[i][k-1],dp[k+1][j])+1; 38 for(int p=2;p<=dp[i][j];p++) ans[p]++; 39 } 40 }else{ 41 if(hw[i][k]==1&&hw[k+1][j]==1&&hw[i][j]==1){ 42 dp[i][j]=max(dp[i][k],dp[k+1][j])+1; 43 for(int p=2;p<=dp[i][j];p++) ans[p]++; 44 } 45 } 46 } 47 } 48 } 49 for(int i=1;i<len;i++) printf("%d ",ans[i]); 50 printf("%d ",ans[len]); 51 return 0; 52 }
以上是关于codeforces853D的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 86C Genetic engineering(AC自动机+DP)
CodeForces 1005D Polycarp and Div 3(思维贪心dp)
(Incomplete) Codeforces 394 (Div 2 only)