POJ - 1390 Blocks

来源:互联网 发布:nokia5250软件下载 编辑:程序博客网 时间:2024/06/14 06:51

题意:n个带颜色的方格排成一列。相同颜色的连成一块区域,你可以选择任意一个区域消去,设这块区域的块数是x,那么你将得到x^2的分值,其右边的方格会左移,与被消去的连在一起,求能得到的最高分值

思路:状态转移DP,让dp[i][j][k]表示将第i块到第j块消去能得到的最大值,那么对于一块区域,我们可以选择直接消去或者让它与前面的相同颜色的一起消去,K的值记录的是在第二种情况下,第j种之后的块数

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 205;int len[MAXN],dp[MAXN][MAXN][MAXN],n,color[MAXN],cnt;int DP(int x,int y,int k){    if (dp[x][y][k])        return dp[x][y][k];    if (x == y)        return (len[x]+k)*(len[x]+k);    dp[x][y][k] = DP(x,y-1,0)+(len[y]+k)*(len[y]+k);    for (int i = x; i < y; i++){        if (color[y] == color[i])            dp[x][y][k] = max(dp[x][y][k],DP(x,i,len[y]+k)+DP(i+1,y-1,0));    }    return dp[x][y][k];}int main(){    int T,ans;    scanf("%d",&T);    for (int t = 1; t <= T; t++){        scanf("%d",&n);        cnt = 0;        memset(len,0,sizeof(len));        memset(color,0,sizeof(color));        int temp;        for (int i = 0; i < n; i++){            scanf("%d",&temp);            if (color[cnt] == temp)                len[cnt]++;            else {                cnt++;                len[cnt]++;                color[cnt] = temp;            }        }        memset(dp,0,sizeof(dp));        ans = DP(1,cnt,0);        printf("Case %d: ",t);        printf("%d\n",ans);    }    return 0;}



原创粉丝点击