题目原文请移步下面的链接
OI
、字符串
、动态规划
假设你有一条长度为 5 的木板,初始时没有涂过任何颜色。你希望把它的 55 个单位长度分别涂上红、绿、蓝、绿、红色,用一个长度为 5 的字符串表示这个目标:RGBGR。
每次你可以把一段连续的木板涂成一个给定的颜色,后涂的颜色覆盖先涂的颜色。例如第一次把木板涂成 RRRRR,第二次涂成 RGGGR,第三次涂成 RGBGR,达到目标。
用尽量少的涂色次数达到目标。
输入仅一行,包含一个长度为 n 的字符串,即涂色目标。字符串中的每个字符都是一个大写字母,不同的字母代表不同颜色,相同的字母代表相同颜色。
仅一行,包含一个数,即最少的涂色次数。
输入 #1
AAAAA
输出 #1
1
输入 #2
RGBGR
输出 #2
3
40% 的数据满足 1≤n≤10。
100% 的数据满足 1≤n≤50。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n';
void best_coder() {
string s;
cin >> s;
int n = s.size();
vector<vector<int>> dp(n + 1, vector<int>(n + 1, 0x3f3f3f));
// 从i~j的区间内需要涂几次才能满足题目要求
for (int i = 0; i < n; ++i) {
dp[i][i] = 1;
}
for (int t = 0; t < n - 1; ++t) {
int i = 0;
for (int j = t + 1; j < n; ++j, ++i) {
if (s[i] == s[j]) {
dp[i][j] = min(dp[i][j - 1], dp[i + 1][j]);
//首尾相等时只用在涂第一次时多涂一个格,判断涂中间需要几次
continue;
}
for (int k = i; k < j; ++k) {
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j]);
// 枚举中间的每一个点判断最优解
}
}
}
cout << dp[0][n - 1];
}
void happy_coder() {
}
int main() {
// 提升cin、cout效率
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
// 小码匠
best_coder();
// 最优解
// happy_coder();
// 返回
return 0;
}