2020-12-5总结

13 篇文章 0 订阅

今天做到了一道题,一道区间dp,和上次的那道题挺类似的,想归类一下这类题型。

那道题

这道题是2020的台北的e题。

题目大意:给定一个由7种字母组成的序列,每次可以消去长度大于等于 m m m的连续相同字符串,然后其他字符再连接到一起(有点类似消消乐)。问是否能够消完 ( n , m < = 500 ) (n,m<=500) n,m<=500

思考:本题和那道题很像,那道题使用的是区间dp的手段,于是思考这道题能不能使用区间dp?

首先发现一个性质:一段连续的字符串,能消掉则一定全部消掉。因为这样不会使得答案变劣。于是一段连续区间可以缩点。

这里我们使用 d p [ l ] [ r ] [ 0 / 1 ] dp[l][r][0/1] dp[l][r][0/1]代表区间 [ l , r ] [l,r] [l,r]中, d p [ 0 ] dp[0] dp[0]能不能完全消掉 [ l , r ] [l,r] [l,r]的字符串(能消掉的dp值为1,不能则为0), d p [ 1 ] dp[1] dp[1]则是 l l l点与 r r r点的颜色相同的情况下,能不能消得区间 [ l , r ] [l,r] [l,r]变成只剩下 l l l点的颜色,且满足剩余个数小于 m m m个(值同上)。

那么对 d p dp dp部分:

For(i, 1, n){
		if(a[i].cnt >= m) dp[i][i][0] = 1;
		else dp[i][i][1] = 1, sum[i][i] = a[i].cnt;
	}
	For(i, 2, n){
		For(l, 1, n - i + 1){
			int r = l + i - 1;
			int p = a[l].c == a[r].c;
			For(k, l, r - 1){
				dp[l][r][0] = max(dp[l][r][0], dp[l][k][0] & dp[k + 1][r][0]);
			}
			if(p){
				if(dp[l + 1][r - 1][0]){
					sum[l][r] = a[l].cnt + a[r].cnt;
					if(sum[l][r] >= m) dp[l][r][0] = 1;
					else dp[l][r][1] = 1;
				}
				For(k, l + 1, r - 1){
					if(a[k].c == a[l].c && ((dp[l][k][0] | dp[l][k][1]) & dp[k + 1][r - 1][0])){
						sum[l][r] = max(sum[l][r], sum[l][k] + a[r].cnt);
						if(sum[l][r] >= m) dp[l][r][0] = 1;
						else dp[l][r][1] = 1;
					}
				}
			}
			//cout<<l<<" "<<r<<" "<<dp[l][r][0]<<" "<<dp[l][r][1]<<" "<<sum[l][r]<<endl;
		}
	}

d p [ l ] [ r ] [ 0 ] dp[l][r][0] dp[l][r][0]可以直接由中间的断点 k k k转移:
d p [ l ] [ r ] [ 0 ] = m a x ( d p [ l ] [ k ] [ 0 ]   &   d p [ k + 1 ] [ r ] [ 0 ] ) dp[l][r][0]=max(dp[l][k][0] \ \& \ dp[k+1][r][0]) dp[l][r][0]=max(dp[l][k][0] & dp[k+1][r][0])
d p [ l ] [ r ] [ 1 ] dp[l][r][1] dp[l][r][1]则可以直接由 l l l r r r点相等直接转移,或者由中间的某个相同的点转移。(详情见代码)
中间点转移,其实是将那些不能单独消去的收到一块来,然后一起消去。这里需要用一个 s u m [ l ] [ r ] sum[l][r] sum[l][r]统计现在最多能收留了多少个 a [ l ] . c a[l].c a[l].c不能单独消去的(满足 l l l r r r点的颜色相同)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值