uva10559 Blocks

来源:互联网 发布:电脑笔顺输入法软件 编辑:程序博客网 时间:2024/04/29 13:51

题意:n个带颜色的方块排成一列,可以选择消去连续的方块,获得的分数是连续的相同颜色的方块的个数的平方,问怎么消去获得最大分数,最大分数是多少。

对于连续的某一段,有两种情况要考虑,第一种是直接把这一段消去,第二种是将它与左边(右边)某一段拼接上再消去,所以就是从一种状态可以转移到这两种状态。。

dp[l][r][k],l,r表示l-r这一段,k表示右边有多少个连续的快可以和这一段拼接消去。。。

dp[l][r][k]=max(dfs(l,p-1,0)+(r-p+1+k)*(r-p+1+k),dfs(l,q,r-p+1+k)+dfs(q+1,p-1,0))..记忆化搜索实现。。。p是与位置r相同颜色的那一段的左边界,q是枚举与r位置相同颜色,切可以作为一段的右边界。

/*************************************************************************> File Name: uva10559.cpp> Author: tjw> Mail: > Created Time: 2014年10月24日 星期五 14时56分03秒 ************************************************************************/#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#include<vector>#include<stack>#include<map>#define ll long long#define ls k<<1#define rs k<<1|1using namespace std;const int MAXN=210;int dp[MAXN][MAXN][MAXN];int a[MAXN];int dfs(int l,int r,int k){    if(l>r)        return 0;    if(dp[l][r][k]!=-1)        return dp[l][r][k];    int p=r;    while(a[r]==a[p]&&p>=l)        p--;    p++;    dp[l][r][k]=dfs(l,p-1,0)+(r-p+1+k)*(r-p+1+k);    for(int q=l;q<p;q++)    {        if(a[q]==a[r]&&a[q]!=a[q+1])        {            dp[l][r][k]=max(dp[l][r][k],dfs(l,q,r-p+1+k)+dfs(q+1,p-1,0));        }    }    return dp[l][r][k];}int main(){    int t,flag=1;    int n,i,j;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        for(i=1;i<=n;i++)        {            scanf("%d",&a[i]);        }        memset(dp,-1,sizeof(dp));        int ans=dfs(1,n,0);        printf("Case %d: %d\n",flag++,ans);    }    return 0;}


0 0
原创粉丝点击