关闭

codeforces 711C - Coloring Trees

50人阅读 评论(0) 收藏 举报
分类:

题目链接

题意:
有n课树,存在m种颜色,希望能分成k段。
然后给出每棵树的初始颜色。
然后给出每棵树染成1~m颜色各自的花费
问最终变成k端花费最少是多少钱。
注意,初始有颜色的树不能染色

思路:
dp[105][105][105]; //前i个树,第i个树染成j这种颜色,构成k段的最小花费
遍历到第i课树,判断一下这棵树是否已经被染色。
* 如果已经被染色,那么花费等于上一棵树的花费
* 如果没有被染色,那么遍历该课树可以被染成的颜色(1~m),花费等于上一棵树的花费+染该棵树的花费

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define INF 0x3f3f3f3f3f3f3f3f
const int maxn=105;
LL dp[105][105][105];  //前i个树,第i个树染成j这种颜色,构成k段的最小花费
int c[105];  //最初树的颜色
int p[105][105];  //第i个树染成j颜色的花费
int main()
{
    int n,m,k;
    cin >> n >> m >> k;
    for (int i = 0; i < n; i++)
    {
        cin >> c[i];
    }
    for (int i = 0; i < n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            cin >> p[i][j];
        }
    }
    memset(dp,INF,sizeof(dp)); //花费初始化为很大值
    //处理第一课树
    if (c[0])  //如果第一棵树有颜色
    {
        dp[0][c[0]][1] = 0;
    }
    else
    {
        for (int i = 1; i <= m; i++) dp[0][i][1] = p[0][i];
    }

    for (int i = 1; i < n; i++)  //到第i个树
    {
        if (!c[i])  //如果这棵树可以被染色
        {
            for (int j = 1; j <= m; j++)  //第i个树染成j这种颜色
            {
                for (int k = 1; k <= i + 1; k++)  //分成了k段
                {
                    for(int h = 1; h <= m; h++)  //前面那个树是h这种颜色
                    {
                        if (j == h)  //如果当前这棵树和前面那棵树染的颜色相同
                        {
                            dp[i][j][k] = min(dp[i][j][k], dp[i - 1][h][k] + p[i][j]);
                        }
                        else  //不同,段数 + 1
                        {
                            dp[i][j][k] = min(dp[i][j][k],dp[i - 1][h][k - 1] + p[i][j]);
                        }
                    }
                }
            }
        }
        else
        {
            for (int k = 1; k <= i + 1; k++)  //分成了k段
            {
                for(int h = 1; h <= m; h++)  //前面那个树是h这种颜色
                {
                    if (c[i] == h)  //如果当前这棵树和前面那棵树染的颜色相同
                    {
                        dp[i][c[i]][k] = min(dp[i][c[i]][k], dp[i - 1][h][k]);
                    }
                    else  //不同,段数 + 1
                    {
                        dp[i][c[i]][k] = min(dp[i][c[i]][k],dp[i - 1][h][k - 1]);
                    }
                }
            }

        }
    }
    LL ans = INF;
    for (int i = 1; i <= m; i++)
    {
        ans = min(ans,dp[n - 1][i][k]);
    }
    if (ans == INF) ans = -1;
    cout << ans << endl;
    return 0;
}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:34055次
    • 积分:3030
    • 等级:
    • 排名:第11481名
    • 原创:282篇
    • 转载:2篇
    • 译文:0篇
    • 评论:1条
    文章分类