zoukankan      html  css  js  c++  java
  • Coloring Trees CodeForces

    Coloring Trees CodeForces - 711C

    题意:有n个点,每个点有一个c值,如果为0表示它没有被染色,否则表示它被染成了c值的颜色。颜色有1到m。把第i棵树染成颜色j所需要的代价是p[i][j]。求最小的代价,使得将每棵树都染色,且如果将连续的一串同色的树视为一个集合,共有k个集合。输出代价,如果不可能达到要求输出-1。

    方法:

    $ans[i][j][k]$表示把前i棵树染好,并且最后一种颜色是j,并且总共有k段的最小费用。

    首先初始化ans全部值为一个很大的树(方便min),然后$ans[0][1..m][0]=0$

    c[i]=0时:更新每个j

    $ans[i][j][k]=min(ans[i-1][j][k]+p[i][j],min{ans[i-1][q][k-1]+p[i][j] | 1<=q<=m})$

    也就是$ans[i][j][k]=min(ans[i-1][j][k],min{ans[i-1][q][k-1] | 1<=q<=m})+p[i][j]$

    c[i]=1时:只更新$j=c[i]$
    $ans[i][j][k]=min(ans[i-1][j][k],min{ans[i-1][q][k-1] | 1<=q<=m})$

    注意:i=1也就是第一棵树需要特判。可以在循环里加条件/在0加值/把第一棵树拉出来单独处理。

     1 #include<cstdio>
     2 #include<cstring>
     3 typedef long long LL;
     4 LL ans[101][101][101];
     5 LL p[101][101];
     6 LL c[101];
     7 LL n,m,k2,minans=0x3f3f3f3f3f3f3f3f;
     8 LL min(LL a,LL b)
     9 {
    10     return a>b?b:a;
    11 }
    12 int main()
    13 {
    14     LL i,j,k,q;
    15     scanf("%I64d%I64d%I64d",&n,&m,&k2);
    16     for(i=1;i<=n;i++)
    17         scanf("%I64d",&c[i]);
    18     for(i=1;i<=n;i++)
    19         for(j=1;j<=m;j++)
    20             scanf("%I64d",&p[i][j]);
    21     memset(ans,0x3f,sizeof(ans));
    22     for(i=1;i<=m;i++)
    23         ans[0][i][0]=0;
    24     for(i=1;i<=n;i++)
    25     {
    26         if(c[i]==0)
    27         {
    28             for(j=1;j<=m;j++)
    29                 for(k=1;k<=k2;k++)
    30                 {
    31                     ans[i][j][k]=ans[i-1][j][k];
    32                     for(q=1;q<=m;q++)
    33                         if(q!=j||i==1)
    34                             ans[i][j][k]=min(ans[i][j][k],ans[i-1][q][k-1]);
    35                     ans[i][j][k]+=p[i][j];
    36                 }
    37         }
    38         else
    39         {
    40             j=c[i];
    41             for(k=1;k<=k2;k++)
    42             {
    43                 ans[i][j][k]=ans[i-1][j][k];
    44                 for(q=1;q<=m;q++)
    45                     if(q!=j||i==1)
    46                         ans[i][j][k]=min(ans[i][j][k],ans[i-1][q][k-1]);
    47             }
    48         }
    49     }
    50     for(i=1;i<=m;i++)
    51         minans=min(ans[n][i][k2],minans);
    52     if(minans==0x3f3f3f3f3f3f3f3f)
    53         printf("-1");
    54     else
    55         printf("%I64d",minans);
    56     return 0;
    57 }
  • 相关阅读:
    BZOJ 1021 循环的债务
    BZOJ 1019 汉诺塔
    BZOJ 1018 堵塞的交通
    BZOJ 1017 魔兽地图
    BZOJ 1016 最小生成树计数
    Luogu 3008 [USACO11JAN]道路和飞机Roads and Planes
    Luogu 3625 [APIO2009]采油区域
    Luogu 4139 上帝与集合的正确用法
    Luogu 3629 [APIO2010]巡逻
    Luogu 3626 [APIO2009]会议中心
  • 原文地址:https://www.cnblogs.com/hehe54321/p/cf-711c.html
Copyright © 2011-2022 走看看