• NOI题库 / 2.6基本算法之动态规划


    总时间限制: 
    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”这四个回文子串。
    对于第三组样例,阿福不需要切割,原串本身就是一个回文串。
    #include <cstring>
    #include <cstdio>
    #define N 1005
    
    int T,len,dp[N];
    char str[N];
    bool judge(int l,int r)
    {
        for(; str[l]==str[r]; ++l,--r);
        if(l>=r) return true;
        else return false;
    }
    int min(int a,int b) { return a>b?b:a; }
    void DP(int l,int r)
    {
        for(int i=l; i<=r; ++i) dp[i]=0x3f3f3f3f;
        dp[0]=1;
        for(int i=l; i<=r; ++i)
            for(int j=0; j<=i; ++j)
            {
                if(judge(j,i))
                {
                    if(j==0) dp[i]=1;
                    else dp[i]=min(dp[i],dp[j-1]+1);
                }
            }
    }
    int main(int argc,char *argv[])
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%s",str);
            len=strlen(str);
            DP(0,len);
            printf("%d
    ",dp[len-1]-1);
        }
        return 0;
    }
  • 相关阅读:
    coredns bug
    Android的Sepolicy
    漫谈fork
    ftrace总结
    Framebuffer
    .net core 5 发送windows10桌面通知
    test_app 测试环境搭建
    GitHub骚操作
    git基于某分支创建新分支
    mysql导入数据load data infile
  • 原文地址:https://www.cnblogs.com/sy1in/p/7855814.html
Copyright © 2020-2023  润新知