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

[程序员代码面试指南]字符串问题-回文最少分割数(DP)

POJ 8471 切割回文 dp北大ACM/ICPC竞赛训练

(动态规划)1547. 切棍子的最小成本(区间dp)/221. 最大正方形 / 1312. 让字符串成为回文串的最少插入次数(区间dp)

Bailian4067 回文数字(Palindrome Number)

dp - bailian 4131:Charm Bracelet

dp - bailian 4141:砝码称重