其他分享
首页 > 其他分享> > cf711 C. Coloring Trees(dp)

cf711 C. Coloring Trees(dp)

作者:互联网

思路:

f(i,j,p)表示第1~i棵树已染色, 染成了j组,第i棵树染成p颜色的最小花费。复杂度 \(O(nkm^2)\)。其实还可以维护2个最值优化到 \(O(nkm)\)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 105;
int n, m, k, col[N], cost[N][N];
ll f[N][N][N];
signed main()
{
    cin >> n >> m >> k;
    for(int i = 1; i <= n; i++) cin >> col[i];
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            cin >> cost[i][j];

    memset(f, 0x3f, sizeof f);
    if(col[1]) f[1][1][col[1]] = 0;
    else for(int i = 1; i <= m; i++) f[1][1][i] = cost[1][i];

    for(int i = 2; i <= n; i++)
    for(int j = 1; j <= k; j++)
        for(int p = 1; p <= m; p++) //i的颜色
        {
            if(col[i] && col[i] != p) continue;
            for(int q = 1; q <= m; q++) //i-1的颜色
            {
                if(col[i-1] && col[i-1] != q) continue;

                if(p == q) //i和i-1同色
                {
                    if(!col[i]) //i无色
                        f[i][j][p] = min(f[i][j][p], f[i-1][j][q] + cost[i][p]);
                    else if(col[i] == q) //i有色
                        f[i][j][p] = min(f[i][j][p], f[i-1][j][q]);
                }
                else //i和i-1异色
                {
                    if(!col[i]) //i无色
                        f[i][j][p] = min(f[i][j][p], f[i-1][j-1][q] + cost[i][p]);
                    else if(col[i] != q) //i有色
                        f[i][j][p] = min(f[i][j][p], f[i-1][j-1][q]);
                }
            }
        }

    ll ans = 1e18;
    for(int i = 1; i <= m; i++) ans = min(ans, f[n][k][i]);
    cout << (ans < 1e18 ? ans : -1);

    return 0;
}

标签:Coloring,int,cf711,ll,nkm,long,cost,col,dp
来源: https://www.cnblogs.com/wushansinger/p/15695520.html