luoguP4170 [CQOI2007]涂色

区间DP连手题.

\(dp[st][ed]\)表示将区间\([st,ed]\)染成合法的最小方案数.

分两种情况讨论.

\(s[st]=s[ed]\)时,\(dp[st][ed]=\min(dp[st+1][ed],dp[st][ed-1])\)

\(s[st]!=s[ed]\)时,\(dp[st][ed]=\min(dp[st][ed],dp[st][i]+dp[i+1][ed])(i\in[st,ed])\)

初始化即将\(dp[i][i]\)置为1.

千万不要被它的数据范围迷惑!!

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define il inline
#define rg register
#define gi read<int>
using namespace std;
const int O = 1010;
template<class TT>
il TT read() {
	TT o = 0,fl = 1; char ch = getchar();
	while (!isdigit(ch) && ch != '-') ch = getchar();
	if (ch == '-') fl = -1, ch = getchar();
	while (isdigit(ch)) o = o * 10 + ch - '0', ch = getchar();
	return fl * o;
}
char s[52];
int n, dp[52][52];
int main() {
	scanf("%s", s + 1); n = strlen(s + 1);
	for (int i = 1; i <= n; ++i) dp[i][i] = 1;
	for (int len = 1; len < n; ++len)
		for (int st = 1; st + len <= n; ++st) {
			int ed = st + len;
			dp[st][ed] = min(dp[st + 1][ed], dp[st][ed - 1]);
			if (s[st] != s[ed]) {
				++dp[st][ed];
				for (int i = st + 1; i < ed; ++i)
					dp[st][ed] = min(dp[st][ed], dp[st][i] + dp[i + 1][ed]);
			}
		}
	printf("%d\n", dp[1][n]);
	return 0;
}
posted @ 2019-10-21 21:07  wuhan2005  阅读(87)  评论(0编辑  收藏  举报