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
  • 相关阅读:
    学习JNA,Jnative
    JNative用法注意事项
    使用JNA替代JNI调用本地方法
    傅盛读书笔记:下一个Moonshot是什么?
    华为内部狂转好文:有关大数据,看这一篇就够了
    ws2_32.dll的妙用与删除 (禁网)
    保护颈椎重点按这三大穴位(图)
    在java中调用python方法
    在Windows中实现Java调用DLL(转载)
    java程序员,英语那点事
  • 原文地址:https://www.cnblogs.com/new-hand/p/7745437.html
Copyright © 2011-2022 走看看