1. 程式人生 > >51nod 1154 dp

51nod 1154 dp

eml -i span turn bits 收藏 long ace fin

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1154

1154 回文串劃分技術分享

基準時間限制:1 秒 空間限制:131072 KB 分值: 40 難度:4級算法題 技術分享 收藏 技術分享 關註 有一個字符串S,求S最少可以被劃分為多少個回文串。 例如:abbaabaa,有多種劃分方式。 a|bb|aabaa - 3 個回文串 a|bb|a|aba|a - 5 個回文串 a|b|b|a|a|b|a|a - 8 個回文串 其中第1種劃分方式的劃分數量最少。 Input
輸入字符串S(S的長度<= 5000)。
Output
輸出最少的劃分數量。
Input示例
abbaabaa
Output示例
3
原本以為N^2會爆炸後來發現好像也不會= =倒是題意搞懵逼我了,題意是必須全部劃分為回文子串,求最少劃分幾個,我以為可以出現非回文子串,就是0......天真
dp[i]表示前i個字符的答案,第i個字符可能單獨也可能與前面的某一串相連構成一個回文串,答案就是 dp[i]=MIN{dp[j]+1 | j<i&&j+1--i構成回文串}
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long
 4 #define inf 0x3f3f3f3f
 5
LL mod=1e9+7; 6 int dp[5005]; 7 char s[5005]; 8 bool ok(int a,int b) 9 { 10 int m=b-((b-a)>>1); 11 for(int i=a,j=b;i<=m;++i,--j) 12 if(s[i]!=s[j]) return 0; 13 return 1; 14 } 15 int main() 16 { 17 int N,i,j; 18 scanf("%s",s+1); 19 N=strlen(s+1); 20 for(i=1;i<=N;++i)
21 { 22 dp[i]=dp[i-1]+1; 23 for(j=0;j<i;++j) 24 { 25 if(ok(j+1,i)&&dp[i]>dp[j]+1) dp[i]=dp[j]+1; 26 } 27 } 28 printf("%d\n",dp[N]); 29 return 0; 30 }

51nod 1154 dp