HDU6212 Zuma

CII.HDU6212 Zuma

一眼区间DP。

首先,我们将串压缩(即将相同颜色的相邻珠子合并)。记coli为位置i的颜色,szi为位置i的珠子数。

我们设f[i,j]表示消去区间[i,j]中所有东西的最小步数。

则有:

f[i,j]=min{3szi|i=jf[i,k]+f[k+1,j]|ik<jf[i+1,j1]+max(0,3sziszj)|coli=coljf[i+1,k1]+f[k+1,j1]|coli=colj=colk,(szi2szj2)szk=1

其中,第一条转移是直接补满3个球;第二条转移是找个地方切一刀;第三条转移是将ij最终合并在一起进行消除;第四条转移是将ij,以及区间中某一个k合并消除,但需要保证有一种消除顺序可以使得k可以先在不与某一边一起消掉的前提下消到那一边,然后再合并两边。

时间复杂度O(Tn3),需要保证常数。

代码:

#include<bits/stdc++.h>
using namespace std;
int T,n,m,sz[210],f[210][210];
bool col[210];
char s[210];
int main(){
	scanf("%d",&T);
	for(int t=1;t<=T;t++){
		scanf("%s",s+1),m=strlen(s+1),n=0;
		col[1]=s[1]-'0',sz[1]=1,n++;
		for(int i=2;i<=m;i++){
			if(s[i]-'0'==col[n])sz[n]++;
			else n++,col[n]=s[i]-'0',sz[n]=1;
		}
		for(int i=1;i<=n;i++)f[i][i]=3-sz[i];
		for(int l=2;l<=n;l++)for(int i=1,j=i+l-1;j<=n;i++,j++){
			f[i][j]=0x3f3f3f3f;
			for(int k=i;k<j;k++)f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]);
			if(col[i]!=col[j])continue;
			f[i][j]=min(f[i][j],f[i+1][j-1]+max(0,3-sz[i]-sz[j]));
			if(sz[i]==2&&sz[j]==2)continue;
			for(int k=i+1;k<j;k++)if(col[k]==col[i]&&sz[k]==1)f[i][j]=min(f[i][j],f[i+1][k-1]+f[k+1][j-1]);
		}
		printf("Case #%d: %d\n",t,f[1][n]);
	}
	return 0;
} 

posted @   Troverld  阅读(49)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示