zoukankan      html  css  js  c++  java
  • Codeforces 607B Zuma

    题意:给你一个长度为n的字符串,每次你可以消去一段连续的回文子串,剩下的两端重新拼接成一个新的串,问最少需要消去多少次。

    思路:这题一开始想不出,不好dp,一个明显的思路是用dp[i][j]表示消去i到j段最少要的次数,但是不知道每次消去后剩下的串的回文串情况,所以我们要换一个思路。其实题目中的回文串已经提醒我们字符串中的每一个字符都要和别的字符匹配后才能消除,那么对于dp[i][j],我们考虑左端点,它被消去只有两种情况,一种是单独消去,另一种是和别的字符匹配消去,第一种情况比较简单,那么对于第二种情况,我们可以枚举[i,j]区间内每一个和它相同的点k,然后先消去区间[i+1,k-1],最后再消去i和k,其实[i+1,k-1]中最后消去的肯定是回文串,一个回文串两端加两个相同的点也是回文串,可以一次消去,所以这里dp[i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k+1][j]);注意还要特判k=i+1的情况。

     ---------Kirito_Acmer

    #include<cstdio>
    #include<algorithm>
    #include<string.h>
    #include<stdlib.h>
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    using namespace std;
    typedef long long LL;
    int a[505],dp[505][505];
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            for(int i =0;i<n;i++) scanf("%d",&a[i]);
            memset(dp,0x3f,sizeof(dp));
            for(int i=0;i<n;i++)dp[i][i]=1;
            for(int l=2;l<=n;l++){
                for(int i=0;i+l-1<n;i++)
                {
                    int j=i+l-1;
                    if(a[i]==a[j]&&l>2) dp[i][j]=dp[i+1][j-1];
                    else if(a[i]==a[j]) dp[i][j]=1;
                    for(int k=i;k<j;k++)
                    {
                        dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);
                    }
                }
            }
            printf("%d
    ",dp[0][n-1]);
        }
    }
    View Code
  • 相关阅读:
    Hadoop Gateway 部署
    java 命令--备忘
    整理下常用硬件性能参数
    python 脚本备份 mysql 数据库到 OSS
    pip 更换国内源
    记录闭包和立即执行函数
    Django 中文乱码问题&富文本显示
    mysql exceeded the 'max_questions' resource 记录
    sql server 数据字典的妙用
    Sublime Text指南
  • 原文地址:https://www.cnblogs.com/new-hand/p/7745437.html
Copyright © 2011-2022 走看看