CF711C Coloring Trees
记 表示前 个点,第 个点染为 ,分成 段的最小花费。
转移方程:
- 第 个点已被染色:。
- 第 个点未被染色:。
时间复杂度 ,可用 st
表优化到 。
#include <bits/stdc++.h>
using namespace std;
#define int long long
inline int read()
{
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-')
f = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
x = x * 10 + c - '0', c = getchar();
return x * f;
}
#define inf 0x7f7f7f7f7f7f
const int _ = 208;
int n, m, k, ans = inf, col[_], cost[_][_], dp[_][_][_];
signed main()
{
n = read(), m = read(), k = read();
for(int i = 1; i <= n; ++i) col[i] = read();
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j) cost[i][j] = read();
memset(dp, inf, sizeof dp);
if(col[1]) dp[1][col[1]][1] = 0;
else for(int i = 1; i <= m; ++i) dp[1][i][1] = cost[1][i];
for(int i = 2; i <= n; ++i)
for(int j = 1; j <= k && j <= i; ++j)
if(col[i])
{
for(int l = 1; l <= m; ++l)
dp[i][col[i]][j] = min(dp[i][col[i]][j], dp[i - 1][l][j - (col[i] == l ? 0 : 1)]);
}
else
{
for(int l = 1; l <= m; ++l)
for(int p = 1; p <= m; ++p)
dp[i][l][j] = min(dp[i][l][j], dp[i - 1][p][j - (l == p ? 0 : 1)] + cost[i][l]);
}
if(col[n]) ans = dp[n][col[n]][k];
else for(int i = 1; i <= m; ++i) ans = min(ans, dp[n][i][k]);
printf("%lld", (ans < inf) ? ans : -1);
return 0;
}
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18121947