题目的大意是给定n棵树,有些树有颜色,有些没有,要求给那些没有颜色的树上色,这个人只认识m种颜色,每种颜色有花费
上完色后要看看每棵树的颜色的种类,连续的种类为一个beauty,要你在上完色的时候构成k个beauty并且花费最少。
构建dp[i][j][k]为第i棵树j个beauty选第k个颜色时的花费。
然后暴力dp,时间复杂度是O(n*k*m^2)
其次inf要写的很大,不然就达不到数据。
参考高手的做法这边inf给2000000000000000ll
代码如下:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 110
long long int dp[N][N][N],a[N],b[N][N];
#define inf 2000000000000000ll
int main(){
int k,i,j,n,m,p,x,q;
cin>>n>>m>>k;
for(i=1;i<=n;i++) cin>>a[i];
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
cin>>b[i][j];
for(i=0;i<=100;i++) for(j=0;j<=100;j++) for(p=0;p<=100;p++) dp[i][j][p]=inf;
dp[0][1][0]=0;
for(i=0;i<n;i++)
for(j=1;j<=k;j++)
for(p=0;p<=m;p++){
if(dp[i][j][p]==inf) continue;
if(a[i+1]!=0){
if(p==0||a[i+1]==p) dp[i+1][j][a[i+1]]=min(dp[i+1][j][a[i+1]],dp[i][j][p]);
if(p!=0&&a[i+1]!=p) dp[i+1][j+1][a[i+1]]=min(dp[i+1][j+1][a[i+1]],dp[i][j][p]);
}
else if(a[i+1]==0){
for(q=1;q<=m;q++)
if(q!=p){
if(p!=0) dp[i+1][j+1][q]=min(dp[i+1][j+1][q],dp[i][j][p]+b[i+1][q]);
if(p==0) dp[i+1][j][q]=min(dp[i+1][j][q],dp[i][j][p]+b[i+1][q]);
}
if(p!=0) dp[i+1][j][p]=min(dp[i+1][j][p],dp[i][j][p]+b[i+1][p]);
}
}
long long int res=inf;
for(i=1;i<=m;i++){
//cout<<dp[n][k][i]<<endl;
res=min(res,dp[n][k][i]);
}
if(res==inf) res=-1;
cout<<res<<endl;
return 0;
}