1. 程式人生 > 其它 >Codeforces711 C. Coloring Trees(dp)

Codeforces711 C. Coloring Trees(dp)

題意:

在這裡插入圖片描述
資料範圍:n,m<=100,塗色花費顏料量a(i,j)<=1e9

解法:

令d[i][j][k]表示前i棵樹,已經j段,末尾為顏色k的最小代價.
對於d[i][j][k],列舉第i+1棵樹的顏色nt,
那麼d[i][j][k]可以向d[i+1][j+(nt!=k)][nt]轉移,轉移代價為塗色代價.

code:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxm=2e6+5;
int d[111][111][111];
int c[111][111];
int
a[111]; int n,m,p; signed main(){ ios::sync_with_stdio(0); cin>>n>>m>>p; for(int i=1;i<=n;i++){ cin>>a[i]; } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ cin>>c[i][j]; } } for(int i=0;i<=n;i++){
for(int j=0;j<=p;j++){ for(int k=0;k<=m;k++){ d[i][j][k]=1e18; } } } d[0][0][0]=0; for(int i=0;i<n;i++){ for(int j=0;j<=p;j++){ for(int k=0;k<=m;k++){ if(d[i][j][k]==1e18)continue; if
(!a[i+1]){ for(int nt=1;nt<=m;nt++){ int f=(nt!=k); if(j+f>p)continue; d[i+1][j+f][nt]=min(d[i+1][j+f][nt],d[i][j][k]+c[i+1][nt]); } }else{ int nt=a[i+1]; int f=(a[i+1]!=k); if(j+f>p)continue; d[i+1][j+f][nt]=min(d[i+1][j+f][nt],d[i][j][k]); } } } } int ans=1e18; for(int k=1;k<=m;k++){ ans=min(ans,d[n][p][k]); } if(ans==1e18)ans=-1; cout<<ans<<endl; return 0; }