[OpenJudge8471][划分DP]切割回文
2016-10-26 13:42
225 查看
切割回文
总时间限制: 1000ms 内存限制: 65536kB
[描述]
阿福最近对回文串产生了非常浓厚的兴趣。如果一个字符串从左往右看和从右往左看完全相同的话,那么就认为这个串是一个回文串。例如,“abcaacba”是一个回文串,“abcaaba”则不是一个回文串。
阿福现在强迫症发作,看到什么字符串都想要把它变成回文的。阿福可以通过切割字符串,使得切割完之后得到的子串都是回文的。
现在阿福想知道他最少切割多少次就可以达到目的。例如,对于字符串“abaacca”,最少切割一次,就可以得到“aba”和“acca”这两个回文子串。
输入输入的第一行是一个整数 T (T <= 20) ,表示一共有 T 组数据。
接下来的 T 行,每一行都包含了一个长度不超过的 1000 的字符串,且字符串只包含了小写字母。输出对于每组数据,输出一行。该行包含一个整数,表示阿福最少切割的次数,使得切割完得到的子串都是回文的。
[样例输入]
3 abaacca abcd abcba
[样例输出]
1 3 0
[提示]
对于第一组样例,阿福最少切割 1 次,将原串切割为“aba”和“acca”两个回文子串。对于第二组样例,阿福最少切割 3 次,将原串切割为“a”、“b”、“c”、“d”这四个回文子串。
对于第三组样例,阿福不需要切割,原串本身就是一个回文串。
[Solution]
这道题思路很像山区建小学,枚举切割的断点进行DP即可。转移方程为:[b]dp[i]=min(dp[i],dp[j]+1)[/b],dp[i]表示前i个字符最少需要切几次,dp[j]+1为这次如果切的话到i的切割次数。
AC代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int T,lenn; int dp[1010]; char ch[1010]; bool pldr[1010][1010]; int main(){ scanf("%d",&T); for(int i=1;i<=T;++i){ memset(dp,0x7f,sizeof(dp)); memset(pldr,0,sizeof(pldr)); dp[0]=0; scanf("%s",ch+1); lenn=strlen(ch+1); for(int j=lenn;j>=1;--j) for(int k=lenn;k>=1;--k) if(ch[j]==ch[k]&&k>=j){ if(j==k) pldr[j][k]=true; else if(k-j+1==2) pldr[j][k]=true; else pldr[j][k]=pldr[j+1][k-1]; } for(int j=1;j<=lenn;++j) for(int k=1;k<=j;++k) if(pldr[k][j]) dp[j]=min(dp[j],dp[k-1]+1); printf("%d\n",dp[lenn]-1); } return 0; }
相关文章推荐
- 【LeetCode131-140】切割回文(值得再看一遍DP),切割词汇(需要看看,DP)
- bailian4122:切割回文(区间dp)
- (UVA - 11584) Partitioning by Palindromes(DP,划分的最小回文串个数)
- DP之钢管切割,最长回文字符串,最长公共子串
- openjudge8471 切割回文
- DP17 最少回文切割次数 Palindrome Partitioning @geeksforgeeks
- 动态规划(DP) 求回文划分
- poj 8471 切割回文(dp+维度压缩)
- Scau 8633 回文划分 mancher + dp
- 切割回文(区间dp)
- 简单dp算法——百炼05:切割回文
- 整数划分问题 DP
- DP算法之整数划分
- atcoder FT Robot(切割的dp)
- 51nod 1092 回文字符串 dp问题
- 51 nod 1201 整数划分(dp)
- 8633 回文划分
- 区间dp模型(石子归并,括号匹配,整数划分)入门经典三道题
- 8782:乘积最大(划分dp)
- 有关计数问题的DP 划分数