zoukankan      html  css  js  c++  java
  • CodeForces #369 C. Coloring Trees DP

    题目链接:C. Coloring Trees

    题意:给出n棵树的颜色,有些树被染了,有些没有。现在让你把没被染色的树染色。使得beauty = k。问,最少使用的颜料是多少。

         K:连续的颜色为一组,一共有多少组。

            颜料用量:p[i][j]表示第i棵树用颜料j染色 需要p[i][j]颜料。

    思路:DP. 

       dp方程:dp[i][j][k] = a 表示前i棵树beauty = j,且第j棵树染色为k时,需要的最少颜料为a。

            状态转移:初始化第一棵树dp[1][1][col[1]or(1~m)].

                          遍历剩下的2~n棵树i,beauty = j (1~min(k, i))时,如果已经被染色了,直接更新dp[i][j or (j+1)][col[i]]为min(dp[i-1][j][1~m])。

                          如果没被染色,尝试染第kkk(1~m)种颜色,并更新dp[i][j or (j+1)][kkk]为min(dp[i-1][j][kk]) (1<=kk<=m, 1<=KKK<=m)。

    喜欢这个题。

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #define maxn 210
    #define inf 1e16
    #define LL long long
    using namespace std;
    
    int col[maxn];
    int p[maxn][maxn];
    LL dp[maxn][maxn][maxn];
    
    int main() {
        int n, m, k;
       // freopen("in.cpp", "r", stdin);
        while(~scanf("%d%d%d", &n, &m, &k)) {
            //input
            for (int i=1; i<=n; ++i) {
                scanf("%d", &col[i]);
            }
    
            for (int i=1; i<=n; ++i) {
                for (int j=1; j<=m; ++j) {
                    scanf("%I64d", &p[i][j]);
                }
            }
    
            //init
            for (int i=1; i<=n; ++i) {
                for (int j=1; j<=k; ++j) {
                    for (int kk=1; kk<=m; ++kk) {
                        dp[i][j][kk] = inf;
                    }
                }
            }
            if (col[1]) dp[1][1][col[1]] = 0;
            else {
                for (int i=1; i<=m; ++i) {
                    dp[1][1][i] = p[1][i];
                }
            }
    
            //solve
            for (int i=2; i<=n; ++i) { ///第i棵树
                for (int j=1; j<=i && j<=k; ++j) { /// i-1 beauty=j
                    if (col[i]) { ///第i棵树颜色已经有了
                        for (int kk=1; kk<=m; ++kk) { ///
                            if (kk == col[i])
                            dp[i][j][col[i]] = min(dp[i][j][col[i]], dp[i-1][j][kk]);
                            else dp[i][j+1][col[i]] = min(dp[i][j+1][col[i]], dp[i-1][j][kk]);
                        }
                    } else {
                        for (int kk=1; kk<=m; ++kk) { ///i
                            for (int kkk=1; kkk<=m; ++kkk) { ///i-1
                                if (kk == kkk)
                                dp[i][j][kk] = min(dp[i][j][kk], dp[i-1][j][kkk]+p[i][kk]);
                                else dp[i][j+1][kk] = min(dp[i][j+1][kk], dp[i-1][j][kkk]+p[i][kk]);
                            }
                        }
                    }
                }
            }
    
            LL ans = inf;
            for (int i=1; i<=m; ++i) {
                ans = min(ans, dp[n][k][i]);
            }
            if (ans == inf) ans = -1;
            printf("%I64d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    数组与指针
    壁纸
    2019/1/11
    指针A
    数组B
    一起来抓老鼠啊!快乐呀!
    打印沙漏
    I think I need a boat house
    币值转换
    《C语言程序设计》编程总结汇总
  • 原文地址:https://www.cnblogs.com/icode-girl/p/5821814.html
Copyright © 2011-2022 走看看