# CodeForces 711C - Coloring Trees DP

118人阅读 评论(0)

/*

http://codeforces.com/problemset/problem/711/C
http://codeforces.com/blog/entry/46830

We compute the following array : dp[i][j][k] denoting the minimum amount of paint needed to color the first i trees such that it has beauty j and the i-th tree is colored by color k, and initialize all these values to INF. We can compute this dp array easily by considering two cases :

1. When the last color used is equal to the current color, then we should compare it with dp[i - 1][j][k] + cost[i][k] if it was originally uncolored or dp[i - 1][j][k] otherwise, since the beauty of the coloring is the same.

2. When the last color used is different from the current color, then we should compare it with dp[i - 1][j - 1][l] + cost[i][k] or dp[i - 1][j - 1][l] for all 1 <= l <= m except when l is equal to the current color, by similar reasoning.

If the current tree is uncolored, we loop through all the m possible colors to color it.

Naively implementing this dp will give an O(nkm2), which is sufficient to pass for this problem. However, it is possible to optimize it into O(nkm) by avoiding iterating through all colors when considering the last color used and store two global minimums. See the code for more the details.

Time Complexity : O(nkm2) or O(nkm)
*/

#include <stdio.h>
#include <string>
#include <cstring>
#include <queue>
#include <algorithm>
#include <functional>
#include <vector>
#include <iomanip>
#include <math.h>
#include <iostream>
#include <sstream>
#include <stack>
#include <set>
#include <bitset>
using namespace std;
typedef long long ll;
const int MAX=105;
const ll INF=(ll)1e18;
ll N,M,K,A[MAX],F[MAX][MAX][MAX],Cost[MAX][MAX];
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
for (int i=0; i<MAX; i++)
for (int j=0; j<MAX; j++)
for (int k=0; k<MAX; k++)
F[i][j][k]=INF;
cin>>N>>M>>K;
for (int i=1; i<=N; i++)
cin>>A[i];
for (int i=1; i<=N; i++)
for (int j=1; j<=M; j++)
cin>>Cost[i][j];
if (A[1]==0)
for (int i=1; i<=M; i++)
F[1][1][i]=Cost[1][i];
else
F[1][1][A[1]]=0;
for (int i=2; i<=N; i++)
{
for (int j=1; j<=K; j++)
{
if (A[i]==0)
{
for (int k=1; k<=M; k++)
{
F[i][j][k]=min(F[i][j][k],F[i-1][j][k]+Cost[i][k]);
for (int l=1; l<=M; l++)
if (l!=k)
F[i][j][k]=min(F[i][j][k],F[i-1][j-1][l]+Cost[i][k]);
}
}
else
{
F[i][j][A[i]]=min(F[i][j][A[i]],F[i-1][j][A[i]]);
for (int l=1; l<=M; l++)
{
if (l!=A[i])
F[i][j][A[i]]=min(F[i][j][A[i]],F[i-1][j-1][l]);
}
}
}
}
ll Ans=INF;
for (int i=1; i<=M; i++)
Ans=min(Ans,F[N][K][i]);
if (Ans>=INF)
Ans=-1;
cout<<Ans;
return 0;
}

0
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：19994次
• 积分：2067
• 等级：
• 排名：第18524名
• 原创：196篇
• 转载：9篇
• 译文：0篇
• 评论：0条
文章分类