poj1390-dp消方块

题目连接

分析:

此题我纠结很久,写不出动态方程,看神人代码以后,用一个三位数组dp[i,j,k],表示从第i个到第j个可以消去的方块个数所能获得的最大值。

那么就有:

dp[i][j][k]=dp[i][r-1][0]+(len[r]+k)^2; len[r]是表示第从r个有连续相同的个数。

代码;

#include<stdio.h>
#include<cstring>
#define Max(a,b) a>b?a:b;
#define N 205
bool vis[N];
int idx;
int a[N],color[N],next[N],len[N];
int dp[N][N][N];

int result()
{      //把dp[N][N][N]放在这里程序崩溃,因为函数里的数组开不下这么大的数值,以后要牢记,这次吃亏了。 
	memset(dp,0,sizeof(dp));
	for(int i=1;i<idx;i++){
		for(int L=1;L+i-1<idx;L++){
			int r=L+i-1;
			for(int k=0;k<=next[r];k++){
				dp[L][r][k]=dp[L][r-1][0]+(len[r]+k)*(len[r]+k);
			for(int j=r-2;j>=L;j--)
			if(color[j]==color[r])
			dp[L][r][k]=Max(dp[L][r][k],dp[L][j][len[r]+k]+dp[j+1][r-1][0]);
		    }
	    }
	}
	return dp[1][idx-1][0];
 }
 
int main()
{
	int t,tmp,n,res,ca=1,i,j;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		scanf("%d",&a[1]);
		idx=res=1;
		for(i=2;i<=n;i++){
			scanf("%d",&a[i]);
			if(a[i]==a[i-1]) res++;
			else {
				color[idx]=a[i-1];
				len[idx++]=res;
				res=1;
			}
		}
		color[idx]=a[n];
		len[idx++]=res;
		memset(vis,0,sizeof(vis));
	    for(i= idx-1; i >= 1; i--){ 						               	
			 if(vis[i]) continue; 
			  next[i] = 0;
			  tmp = i;
			  for(j = i-2; j >= 1; j--)
				if(color[j] == color[tmp]){
					next[j] = next[tmp] + len[tmp];
					tmp = j;
					vis[j--] =1;
				}
		}
		printf("Case %d: %d\n",ca++,result());
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值