http://codeforces.com/problemset/problem/711/C
题意:现在有一排树,要给每棵树都要涂上颜色,而有些树初始时是有颜色的,有颜色的树不能再被涂色。给不同的树涂不同的颜色时所耗费的颜料数不同,现在问使这一排树的涂色之美为给定某个值时最少需要的总涂料数是多少。
涂色之美(beauty of the coloring):颜色相同的连续段的最少个数。比如 2, 1, 1, 1, 3, 2, 2, 3, 1, 3的beauty就是7,因为 {2}, {1, 1, 1}, {3}, {2, 2}, {3}, {1}, {3}分配把连续段个数搞得最少。也就是求从头到尾有多少相同数字的串。
题解:这道题是dp的题。
dp[i][j][k]为涂前i棵树后beauty值为j,且第i棵树涂色为k时的最少涂料数。
如果第i棵树已经被涂色c[i],那么dp[i][j][c[i]] = min (dp[i - 1][j][c[i]], dp[i - 1][j - 1][l])(1<=l<= m && l != c[i])。
如果第i棵树还没有被涂色,那么就要枚举第i棵树涂各种颜色的情况,dp[i][j][k] = min (dp[i - 1][j][k] + cost(i, k), dp[i - 1][j - 1][l] + cost(i, k))(1<=k <= m && 1<=l<= m && l != k)
初始化:将dp中所有值都初始化为INF。
边界:如果第1棵树已经被涂色,那么dp[1][1][c[1]] = 0,如果没有被涂色,dp[1][1][k] = cost(1, k)(1<=k<=m)
思考:
1、不要看着条件多就放弃。
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 200;
long long dp[maxn][maxn][maxn];
int c[maxn], p[maxn][maxn];
const long long INF = 1e18;
int main()
{
int n, m, r;
scanf ("%d%d%d", &n, &m, &r);
for (int i = 1; i <= n; i++) {
scanf ("%d", &c[i]);
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
scanf ("%d", &p[i][j]);
}
}
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= r; j++) {
for (int k = 0; k <= m; k++) {
dp[i][j][k] =INF;
}
}
}
if (c[1] == 0) {
for (int i = 1; i <= m; i++) {
dp[1][1][i] = p[1][i];
}
} else {
dp[1][1][c[1]] = 0;
}
for (int i = 2; i <= n; i++) {
if (c[i] == 0) {
for (int j = 1; j <= m; j++) {//涂j色
for (int k = 1; k <= r; k++) {//beauty为k
for (int l = 1; l <= m; l++) {//上一个的涂色
if (l == j) {
dp[i][k][j] = min (dp[i][k][j], dp[i - 1][k][l] + p[i][j]);
} else {
dp[i][k][j] = min (dp[i][k][j], dp[i - 1][k - 1][l] + p[i][j]);
}
}
}
}
} else {
for (int k = 1; k <= r; k++) {//beauty为k
for (int l = 1; l <= m; l++) {//上一个的涂色
if (l == c[i]) {
dp[i][k][c[i]] = min (dp[i][k][c[i]], dp[i - 1][k][l]);
} else {
dp[i][k][c[i]] = min (dp[i][k][c[i]], dp[i - 1][k - 1][l]);
}
}
}
}
}
long long ans = INF;
for (int i = 1; i <= m; i++) {
ans = min (ans, dp[n][r][i]);
}
if (ans == INF) ans = -1;
cout << ans << endl;
return 0;
}