【ybt高效进阶5-2-2】【luogu P4170】木板涂色 / 涂色

木板涂色 / 涂色

题目链接:ybt高效进阶5-2-2 / luogu P4170

题目大意

给你一个没有颜色的木板,再给你最后要变成的颜色。
你每次可以选一段连续的区间染上任意一种颜色,后面染的颜色会覆盖前面的颜色。
问你要变成给出的木板颜色至少要操作多少次。

思路

看到区间,容易想到区间 DP。
f i , j f_{i,j} fi,j 为将 i i i j j j 的区间染色成要的颜色要的最少次数。
那答案就是 f 1 , n f_{1,n} f1,n
那我们考虑要怎么转移。

显然如果只有一个位置,即 i = j i=j i=j,那一定是一次就好。
那如果 a i = a j a_i=a_j ai=aj(同一个颜色),那我们完全可以 f i , j − 1 f_{i,j-1} fi,j1 f i + 1 , j f_{i+1,j} fi+1,j 边缘的颜色再多往左或往右延伸一个位置,不用加。
那如果不是,我们就要枚举中间分割的地方。

那就根据这个 DP 就可以了。

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#define INF 0x3f3f3f3f3f3f3f3f

using namespace std;

int n, f[101][101];
char a[101];

int work(int l, int r) {
	if (a[l] == a[r]) return min(f[l][r - 1], f[l + 1][r]);
	//头尾相同,可以直接将最后一次染色的范围增大
	int re = INF;
	for (int i = l; i < r; i++)//不相同,要枚举断开的地方
		re = min(re, f[l][i] + f[i + 1][r]);
	return re;
}

int main() {
	scanf("%s", a + 1);
	n = strlen(a + 1);
	
	for (int i = 1; i <= n; i++) f[i][i] = 1;
	for (int i = 2; i <= n; i++)
		for (int st = 1; st + i - 1 <= n; st++) {
			f[st][st + i - 1] = work(st, st + i - 1);
		}
	
	printf("%d", f[1][n]);
	
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值