51nod 1154 dp

Posted zzq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod 1154 dp相关的知识,希望对你有一定的参考价值。

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的主要内容,如果未能解决你的问题,请参考以下文章

51Nod-1154 回文串划分

区间dp 51nod1021

51Nod 1450 闯关游戏 —— 期望DP

51nod 1021 石子归并 (动态规划 简单代码)

51Nod 1042 数字0-9的数量(数位DP)

51Nod 1021~1023 石子合并 (逐步加强版) dp