【动态规划】Codeforces 711C Coloring Trees

题目链接:

  http://codeforces.com/problemset/problem/711/C

题目大意:

  给N棵树,M种颜色,已经有颜色的不能涂色,没颜色为0,可以涂色,每棵树I涂成颜色J花费PIJ。求分成K个颜色段(1112221为3个颜色段)的最小花费。无解输出-1.

题目思路:

  【动态规划】

  f[i][j][k]表示前i个树分成j段,最后一个颜色是k的花费。

  根据当前这棵树是否可以涂色,上一棵树是否可以涂色转移。

  直接枚举这个树和上棵树的颜色,N4居然没T。 

 

  1 //
  2 //by coolxxx
  3 //#include<bits/stdc++.h>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<string>
  7 #include<iomanip>
  8 #include<map>
  9 #include<stack>
 10 #include<queue>
 11 #include<set>
 12 #include<bitset>
 13 #include<memory.h>
 14 #include<time.h>
 15 #include<stdio.h>
 16 #include<stdlib.h>
 17 #include<string.h>
 18 //#include<stdbool.h>
 19 #include<math.h>
 20 #define min(a,b) ((a)<(b)?(a):(b))
 21 #define max(a,b) ((a)>(b)?(a):(b))
 22 #define abs(a) ((a)>0?(a):(-(a)))
 23 #define lowbit(a) (a&(-a))
 24 #define sqr(a) ((a)*(a))
 25 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
 26 #define mem(a,b) memset(a,b,sizeof(a))
 27 #define eps (1e-8)
 28 #define J 10
 29 #define mod 1000000007
 30 #define MAX 0x7f7f7f7f
 31 #define PI 3.14159265358979323
 32 #define N 104
 33 using namespace std;
 34 typedef long long LL;
 35 int cas,cass;
 36 int n,m,lll,ans;
 37 int c[N];
 38 LL aans;
 39 LL a[N][N];
 40 LL f[N][N][N];
 41 int main()
 42 {
 43     #ifndef ONLINE_JUDGE
 44 //    freopen("1.txt","r",stdin);
 45 //    freopen("2.txt","w",stdout);
 46     #endif
 47     int i,j,k,l;
 48 //    for(scanf("%d",&cass);cass;cass--)
 49 //    for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
 50 //    while(~scanf("%s",s+1))
 51     while(~scanf("%d",&n))
 52     {
 53         scanf("%d%d",&m,&cas);
 54         for(i=1;i<=n;i++)
 55             scanf("%d",&c[i]);
 56         for(i=1;i<=n;i++)
 57             for(j=1;j<=m;j++)
 58                 scanf("%I64d",&a[i][j]);
 59         mem(f,0x7f);
 60         c[0]=m+1,f[0][0][m+1]=0;
 61         for(i=1;i<=n;i++)
 62         {
 63             if(c[i]!=0)
 64             {
 65                 if(c[i-1]!=0)
 66                 {
 67                     for(j=1;j<=min(i,cas);j++)
 68                     {
 69                         if(c[i]!=c[i-1])
 70                             f[i][j][c[i]]=min(f[i][j][c[i]],f[i-1][j-1][c[i-1]]);
 71                         else f[i][j][c[i]]=min(f[i][j][c[i]],f[i-1][j][c[i-1]]);
 72                     }
 73                 }
 74                 else//c[i]!=0 c[i-1]=0
 75                 {
 76                     for(j=1;j<=min(i,cas);j++)
 77                     {
 78                         for(k=1;k<=m;k++)
 79                         {
 80                             if(k!=c[i])
 81                                 f[i][j][c[i]]=min(f[i][j][c[i]],f[i-1][j-1][k]);
 82                             else f[i][j][c[i]]=min(f[i][j][c[i]],f[i-1][j][k]);
 83                         }
 84                     }
 85                 }
 86             }
 87             else if(c[i-1]==0)//c[i]=0
 88             {
 89                 for(j=1;j<=min(i,cas);j++)
 90                 {
 91                     for(k=1;k<=m;k++)
 92                     {
 93                         for(l=1;l<=m;l++)
 94                         {
 95                             if(l==k)f[i][j][k]=min(f[i][j][k],f[i-1][j][l]+a[i][k]);
 96                             else f[i][j][k]=min(f[i][j][k],f[i-1][j-1][l]+a[i][k]);
 97                         }
 98                     }
 99                 }
100             }
101             else//c[i]=0,c[i-1]!=0
102             {
103                 for(j=1;j<=min(i,cas);j++)
104                 {
105                     for(k=1;k<=m;k++)
106                     {
107                         if(k!=c[i-1])
108                             f[i][j][k]=min(f[i][j][k],f[i-1][j-1][c[i-1]]+a[i][k]);
109                         else f[i][j][k]=min(f[i][j][k],f[i-1][j][c[i-1]]+a[i][k]);
110                     }
111                 }
112             }
113         }
114         aans=f[0][0][0];
115         for(i=1;i<=m;i++)
116             aans=min(aans,f[n][cas][i]);
117         if(aans==f[0][0][0])puts("-1");
118         else printf("%I64d\n",aans);
119     }
120     return 0;
121 }
122 /*
123 //
124 
125 //
126 */
View Code

 

posted @ 2016-08-30 14:58  Cool639zhu  阅读(290)  评论(0编辑  收藏  举报