cf711 C. Coloring Trees(dp)
阿新 • • 發佈:2021-12-15
思路:
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; }