zoukankan      html  css  js  c++  java
  • [Uva10559]Blocks(区间DP)

    Description

    题意:有一排数量为N的方块,每次可以把连续的相同颜色的区间消除,得到分数为区间长度的平方,然后左右两边连在一起,问最大分数为多少。

    (1leq Nleq200)

    Solution

    区间DP,对于一个连续的同色区间,可以直接消掉,或者从左边或者右边搞到和它同色的区间和在一起再一起消掉。

    读入序列时预处理一下,将各个连续同色区间处理为一个点,记录它的颜色和长度,便于处理

    然后就是区间DP啦,虽然要表示左边和右边,但是左边状态也可以表示为左边序列的右边,就只要开3维就行了

    那么(dp[i][j][k])表示区间(i)到区间(j)且在区间(j)右边添加(k)个格子的最大分数

    1. 直接消除,即左边不考虑,为(dp[i][j-1][0]+(len[j]+k)^2)
    2. 考虑左边,在(j)右边枚举(p),且(color[j]==color[p]),则为(max{dp[i][p][k+len[j]]+dp[p+1][j-1][0]})

    Code

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define sq(a) ((a)*(a))
    #define N 210
    using namespace std;
    
    int T,col[N],dp[N][N][N],n,len[N];
    
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    
    int DP(int l,int r,int k){
    	int &tmp=dp[l][r][k];
    	if(tmp>-1) return tmp;
    	
    	tmp=DP(l,r-1,0)+sq(len[r]+k);
    	for(int p=l;p<r;++p){
    		if(col[p]!=col[r]) continue;
    		tmp=max(tmp,DP(l,p,k+len[r])+DP(p+1,r-1,0));
    	}
    	return tmp;
    }
    
    int main(){
    	T=read();
    	for(int Ca=1;Ca<=T;++Ca){
    		memset(dp,-1,sizeof(dp));
    		memset(len,0,sizeof(len));
    		int L=read(),a=read(),l=1;
    		n=0;
    		for(int i=2;i<=L;++i){
    			int b=read();
    			if(b==a) l++;
    			else{
    				col[++n]=a;
    				len[n]=l;
    				l=1;
    				a=b;
    			}
    		}
    		col[++n]=a,len[n]=l;
    		for(int i=1;i<=n;++i) {dp[i][i][0]=sq(len[i]);dp[i][i-1][0]=0;}
    		printf("Case %d: %d
    ",Ca,DP(1,n,0));
    	}
    	return 0;
    }
    
  • 相关阅读:
    C语言PRO2
    pro5
    自我介绍
    李喆第5次作业
    李喆的作业
    一个队列类的实现(比delphi自带的速度快70倍)
    关于 IHTMLDocument4 在 Delphi7.0 中不能编译的的解决方法
    高吞吐量的一个日志函数类_用于IOCP (Delphi)
    PostThreadMessage在线程中应用(以多线程网站数据采集为例)
    微软企业库5 加密篇
  • 原文地址:https://www.cnblogs.com/void-f/p/8146222.html
Copyright © 2011-2022 走看看