P5189 [COCI2009-2010#5] ZUMA 题解

P5189

容易想到区间 dp,考虑设计状态。

首先如果只有 l,r 两维的话,是无法转移的。然后发现 m 是转移的一个必要的条件,可加入 m 这一维。由于是区间 dp,所以只需考虑向左或向右加珠子,不妨令 fi,j,k 消除 [i,j] 以及 i 前面的 k 颗珠子的的最少步数。

f 首先要赋为一个极大值,初始条件显然为 fi,i,j=K1j

转移需要分类讨论一下。

首先,如果 ai=ai+1,就可以从 fi+1,j,k+1 递推而来。
然后也可以由 fi,j,k+1 递推得到,即在前面多一颗珠子。还有一个就是找到某点 p,满足 ai=ap,此时就是 fi+1,p1,0+fp,j,k+1

fi,j,k=min{fi+1,j,k+1,minp=i+1,ai=apj{fi+1,p1,0+fp,j,k+1},fi,j,k+1+1}

代码:

const int N=110;
int n,m;
int a[N],f[N][N][N];

int main(){
	memset(f,0x3f,sizeof(f));
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		for(int j=0;j<m;j++)
			f[i][i][j]=m-1-j;
	}
	for(int len=2;len<=n;len++)
		for(int i=1;i<=n-len+1;i++){
			int j=i+len-1;
			for(int k=m-1;k>=0;k--){
				if(k==m-1)
					f[i][j][k]=min(f[i][j][k],f[i+1][j][0]);
				else
					f[i][j][k]=min(f[i][j][k],f[i][j][k+1]+1);
				if(a[i]==a[i+1])
					f[i][j][k]=min(f[i][j][k],f[i+1][j][min(k+1,m-1)]);
				for(int l=i+1;l<j;l++)
					if(a[i]==a[l+1])
						f[i][j][k]=min(f[i][j][k],f[i+1][l][0]+f[l+1][j][min(k+1,m-1)]);
			}
		}
	cout<<f[1][n][0]<<endl;
	return 0;
}
posted @   Pengzt  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示