poj1390 Blocks

来源:互联网 发布:网络红外高清摄像头 编辑:程序博客网 时间:2024/06/05 12:13

    此题为区间动态规划,但此题的状态转移真的非常巧妙。首先将木块按颜色分成段,每一段的颜色相同。dp[i][j][k]表示消去[i,j]段得到的最大分数,其中k表示第j段后面与它颜色相同的段的长度,且这一段已经缚到第j段了。现在来考虑第j段,它要么单独消去,要么与[i,j-1]中与它颜色相同的段一起消去。

所以状态转移方程:

dp[i][j][k]=max(dp[i][j-1]+(a[j]+k)*(a[j]+k),dp[i][t][a[j]+k]+dp[t+1][j-1][0]).

其中a[i]表示第i段的长度。

//dp[i][j][k]表示合并第i块到第j块的最大得分,其中k表示附加在第j块后面且与第j块具有相同颜色的块的长度//考虑第j块,它要么单独消去,要么与在它前面的某块共同消去,即对于第j块有两种决策。 #include<iostream>#include<cstdio>#include<cstring>using namespace std;const int maxn=205;struct {int col,len;//记录颜色和长度 }a[maxn];int dp[maxn][maxn][maxn];int t,n,m;inline int max(int a,int b){return a>b?a:b;}int dfs(int i,int j,int k){if(dp[i][j][k]!=-1)return dp[i][j][k];if(i>j)return 0;dp[i][j][k]=dfs(i,j-1,0)+(a[j].len+k)*(a[j].len+k);//单独消去 for(int p=i;p<j;p++)if(a[p].col==a[j].col)//找到与自己颜色相同的段,与它一起消去 dp[i][j][k]=max(dp[i][j][k],dfs(i,p,a[j].len+k)+dfs(p+1,j-1,0));return dp[i][j][k];}int main(){int i,Case,pre,cur;cin>>t;Case=0;while(t--){Case++;cin>>n;i=0;pre=-1;while(n--){cin>>cur;if(cur!=pre){i++;a[i].col=cur;a[i].len=1;pre=cur;continue;}a[i].len++;}memset(dp,-1,sizeof(dp));dfs(1,i,0);printf("Case %d: %d\n",Case,dp[1][i][0]);}//system("pause");return 0;}


原创粉丝点击