• UVA 10559 Blocks——区间dp


    题目:https://www.luogu.org/problemnew/show/UVA10559

    应该想到区间dp。但怎么设计状态?

    因为连续的东西有分值,所以应该记录一下连续的有多少个。

      只要记录与边界连续的有多少个就能涵盖所有的连续了。只记一边的边界即可。

    两个转移:用掉记录的那些连续的 或 在自己区间中再找一个一样颜色的使连续数量+1。

      用掉了以后剩余部分的连续长度就是0。也许 j-1 和 j 同色,但这个可以在另一个转移里体现,所以没问题。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=205;
    int T,n,a[N],dp[N][N][N];
    int rdn()
    {
        int ret=0,fx=1; char ch=getchar();
        while(ch>'9'||ch<'0'){if(ch=='-')fx=-1; ch=getchar();}
        while(ch>='0'&&ch<='9') ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
        return ret*fx;
    }
    void init()
    {
        memset(dp,0,sizeof dp);
    }
    int main()
    {
        T=rdn();
        for(int t=1;t<=T;t++)
        {
            init();
            n=rdn(); for(int i=1;i<=n;i++) a[i]=rdn();
            for(int i=1;i<=n;i++)
                for(int k=0;k<=(n-i);k++)
                    dp[i][i][k]=(k+1)*(k+1);
            for(int d=2,lm=n-d+1;d<=n;d++)
                for(int i=1,j,LM;i<=lm;i++)
                {
                    j=i+d-1; LM=n-j;
                    for(int k=0;k<=LM;k++)
                    {
                        dp[i][j][k]=dp[i][j-1][0]+(k+1)*(k+1);
                        for(int l=i;l<j;l++)
                            if(a[l]==a[j])
                                dp[i][j][k]=max(dp[i][j][k],
                                                dp[i][l][k+1]+dp[l+1][j-1][0]);
                        //printf("dp[%d][%d][%d]=%d
    ",i,j,k,dp[i][j][k]);
                    }
                }
            printf("Case %d: %d
    ",t,dp[1][n][0]);
        }
        return 0;
    }
  • 相关阅读:
    GDUFE ACM-1050
    hdu-2020
    hdu-2055
    hdu-2734
    GDUFE ACM-1145
    GDUFE ACM-1127
    GDUFE ACM-1126
    GDUFE ACM-1125
    GDUFE ACM-1124
    GDUFE ACM-1123
  • 原文地址:https://www.cnblogs.com/Narh/p/9672972.html
Copyright © 2020-2023  润新知