Bailian4122 切割回文DP
Posted 海岛Blog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bailian4122 切割回文DP相关的知识,希望对你有一定的参考价值。
4122:切割回文
总时间限制: 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”这四个回文子串。
对于第三组样例,阿福不需要切割,原串本身就是一个回文串。
问题链接:Bailian4122 切割回文
问题简述:(略)
问题分析:动态规划问题。
定义状态dp[i]: 前i个字符的最小切割回文,若dp[i]=INF(0x3F3F3F3F,初值)则表示不可完成。
dp[0] = 0
状态转移 dp[i]=min(dp[i],dp[j-1]+1 ) ( 1 < = j < = i 且 S [ i . . j ] 是 回 文 串 )
程序说明:(略)
参考链接:(略)
题记:(略)
AC的C++语言程序如下:
/* Bailian4122 切割回文 */
#include <bits/stdc++.h>
using namespace std;
const int N = 1000;
char s[N + 1];
int dp[N + 1];
bool judge(int l, int r)
{
while (l <= r) {
if (s[l] != s[r]) return false;
l++, r--;
}
return true;
}
int main()
{
int t;
scanf("%d", &t);
while (t--) {
scanf("%s", s);
memset(dp, 0x3F, sizeof dp);
int len = strlen(s);
for (int i = 0; i < len; i++)
for (int j = 0; j <= i; j++)
if (judge(j, i)) {
if (j == 0) dp[i] = 0;
else dp[i] = min(dp[i], dp[j - 1] + 1);
}
printf("%d\\n", dp[len - 1]);
}
return 0;
}
以上是关于Bailian4122 切割回文DP的主要内容,如果未能解决你的问题,请参考以下文章
POJ 8471 切割回文 dp北大ACM/ICPC竞赛训练
(动态规划)1547. 切棍子的最小成本(区间dp)/221. 最大正方形 / 1312. 让字符串成为回文串的最少插入次数(区间dp)
Bailian4067 回文数字(Palindrome Number)