UVA - 10559 Blocks 给状态增加一个维度

题目

n个不同颜色的方块排成一行,每次消去一段长度为x的连续相同颜色方块(这一段是指直到这种颜色的边界为止),可以得到 x 2 x^2 积分,问最多可以得到多少积分

分析

这一题是区间动态规划,但是截然不同的是,如果按照dp[i,j]从i到j连续的一段来表示状态,那么无法表示XAXBXCX这种的最优解,因为它是消除了内部的分段A,B,C之后,还要把剩下的重新拼起来,而以前见到的都只有划分,没有重新拼接这一个部分

这道题的状态和转移方程非常巧妙,让我想估计一天都想不出,关键是给状态增加一个维度k表示后缀,得到的状态是dp[i][j][k]表示从方块i到方块j这一段,后面还有k个和方块j颜色相同的方块时的最大得分
首先对于右端的方块来说,只看消去时的结果,他要么是被独自消去的,要么是两端隔开的被连在了一起之后消除,所以决策就有两个

  1. 消除最右端的那一段方块(连带着后缀一起), d p [ i ] [ j ] [ k ] = d p [ i ] [ p 1 ] [ 0 ] + ( j p + k + 1 ) 2 , [ p , j ] p [ i j ] j dp[i][j][k]=dp[i][p-1][0]+(j-p+k+1)^2,其中[p,j]中的p是[i,j]中,与j相同颜色的连续木块区间能够到达的最左端
  2. 消除中间的一段, q < p i < = q < = j , c o l o r [ q ] = = c o l o r [ j ] c o l o r [ q + 1 ] ! = c o l o r [ j ] q<p且i<=q<=j,color[q]==color[j] 且 color[q+1] !=color[j] ,按照这个要求可以找出很多个q,枚举可能的q, d p [ i ] [ j ] [ k ] = m a x q ( d p ( q + 1 , p 1 , 0 ) + d p ( i , q , j p + k + 1 ) q q ) dp[i][j][k]=max_q(dp(q+1, p-1, 0) + dp(i, q, j-p+k+1)|q\in满足条件的q值集合) ,这时状态转移方程中分为两部分,一个是被处理的中间部分dp(q+1, p-1, 0),另一个是剩下的dp(i, q, j-p+k+1),可以看到[p,j]变成了后缀部分

状态有 O n 3 O(n^3) 个,决策有O(n)个,时间复杂度 O ( n 4 ) O(n^4) ,但实际使用的状态数量比较少,所以时间消耗不高

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=205;
int t,kase,n,color[maxn],dp[maxn][maxn][maxn];

int DP(int i,int j,int k){
    if(i>j) return 0;
    int &t=dp[i][j][k];
    if(t>=0) return t;
    int p=j-1;
    while(p>=i && color[p]==color[j]) p--;
    ++p;
    t=DP(i,p-1,0)+(j-p+1+k)*(j-p+1+k);
    for(int q=i;q<p;++q){
        if(color[q]==color[j] && color[q+1]!=color[j]){
            t=max(t,DP(q+1,p-1,0)+DP(i,q,j-p+1+k));
        }
    }
    return t;
}

int main(void){
    cin>>t;
    kase=1;
    while(kase<=t){
        cin>>n;
        for(int i=0;i<n;++i) scanf("%d",&color[i]);
        for(int i=0;i<n;++i){
            for(int j=0;j<n;++j){
                for(int k=0;k<n;++k)
                    dp[i][j][k]=-1;
            }
        }
        int ans=DP(0,n-1,0);
        printf("Case %d: %d\n",kase++,ans);
    }
}
发布了15 篇原创文章 · 获赞 0 · 访问量 168

猜你喜欢

转载自blog.csdn.net/zpf1998/article/details/104020632