poj 1390 动态规划

思路:

黑书的例题

#include<iostream>

#include<cstring>

#include<algorithm>

#include<cmath>

#include<cstdio>

#define Maxn 210

using namespace std;

int dp[Maxn][Maxn][Maxn],col[Maxn],len[Maxn],pre[Maxn],aper[Maxn],after[Maxn],vi[Maxn];

int main()

{

    int t,n,i,j,x,k,Case=0;

    int cnt=0;

    scanf("%d",&t);

    while(t--){

        memset(dp,0,sizeof(dp));

        memset(pre,0,sizeof(pre));

        memset(len,0,sizeof(len));

        memset(aper,0,sizeof(aper));

        cnt=0;

        scanf("%d",&n);

        for(i=1;i<=n;i++){

            scanf("%d",&x);

            if(x!=col[cnt])

                col[++cnt]=x,len[cnt]=1,pre[cnt]=aper[x],aper[x]=cnt;

            else

                len[cnt]++;

        }

        memset(vi,0,sizeof(vi));

        for(i = cnt; i >= 1; i--){

            if(vi[i]) continue;

            after[i] = 0;

            int tmp = i;

            for(j = i-1; j >= 1; j--)

                if(col[j] == col[tmp]){

                    after[j] = after[tmp] + len[tmp];

                    tmp = j;

                    vi[j--] = true;

                }

        }

        int l;

        for(l=0;l<=cnt;l++){

            for(i=1;i+l<=cnt;i++){

                j=i+l;

                for(k=0;k<=after[j];k++){

                    dp[i][j][k]=dp[i][j-1][0]+(len[j]+k)*(len[j]+k);

                    int p=pre[j];

                    while(p>=i){

                    dp[i][j][k]=max(dp[i][j][k], dp[i][p][k+len[j]]+dp[p+1][j-1][0]);

                    p=pre[p];

                    }

                }

            }

        }

        printf("Case %d: %d\n",++Case,dp[1][cnt][0]);

    }

    return 0;

}

 

你可能感兴趣的:(动态规划)