# CodeForces 711C - Coloring Trees DP

/*

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;
}



• 本文已收录于以下专栏：

举报原因： 您举报文章：CodeForces 711C - Coloring Trees DP 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)