Codeforces Round #369 (Div. 2)-C Coloring Trees

题目大意:有n个点,由m种颜料,有些点没有涂色,有些点已经涂色了,告诉你每个点涂m种颜色的价格分别是多少,

让你求将这n个点分成k段最少需要多少钱。

思路:动态规划,我们另dp[ i ][ j ][ k ] 表示到i个点为止,分成j段,最后一段的颜色为k的最少值,然后就能很容易地

写出状态转移方程。

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N=105;
 5 const ll inf=0x3f3f3f3f3f3f3f3f;
 6 ll dp[N][N][N],c[N],cost[N][N];
 7 int n,m,k;
 8 int main()
 9 {
10     memset(dp,inf,sizeof(dp));
11     scanf("%d%d%d",&n,&m,&k);
12     for(int i=1;i<=n;i++) scanf("%lld",&c[i]);
13     for(int i=0;i<=m;i++) dp[0][0][i]=0;
14     for(int i=1;i<=n;i++)
15     {
16         for(int j=1;j<=m;j++) scanf("%lld",&cost[i][j]);
17     }
18     for(int i=1;i<=n;i++)
19     {
20         for(int j=1;j<=k;j++)
21         {
22             for(int u=1;u<=m;u++)
23             {
24                 if(c[i] && u!=c[i]) continue;
25                 for(int v=0;v<=m;v++)
26                 {
27                     if(u==v) dp[i][j][u]=min(dp[i][j][u],dp[i-1][j][v]);
28                     else dp[i][j][u]=min(dp[i][j][u],dp[i-1][j-1][v]);
29                 }
30                 if(!c[i]) dp[i][j][u]+=cost[i][u];
31             }
32         }
33     }
34     ll ans=inf;
35     for(int i=1;i<=m;i++) ans=min(ans,dp[n][k][i]);
36     printf("%lld
",ans==inf? -1:ans);
37     return 0;
38 }
View Code
原文地址:https://www.cnblogs.com/CJLHY/p/7885832.html