CodeForces

来源:互联网 发布:三毛梦里花落知多少txt 编辑:程序博客网 时间:2024/04/30 11:02

题目大意

输入n,m,k,n表示有多少棵树,m表示有多少中颜色可以给树添加,k表示完美树的个数,
下面的n行表示给第i棵树染色j需要的花费,问把树染成k个完美树需要的最小花费。
第二行0表示该树没有颜色,其余表示树已经有该颜色了不能添加颜色了

解题思路

dp[i][j][k]表示染完第i棵树,使用的是j燃料,完美数为k的情况下的最小花费,很明显我们要根据当前书是否被染色进行判断,所以状态转移方程为
如果当前没有被染色:dp[i][j][k]=min{dp[i][j][k],dp[i1][j][k]+w[i][j]}
如果已经被染色了 :dp[i][j][k]=min{dp[i][j][k],dp[i1][j][k]}

AC代码

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const int MX = 105;const LL INF = 0x3f3f3f3f3f3f3f;LL dp[MX][MX][MX];int A[MX],w[MX][MX];int main(){    int n,m,K;//freopen("in.txt","r",stdin);    scanf("%d%d%d",&n,&m,&K);    for(int i=1;i<=n;i++) scanf("%d",&A[i]);    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++) scanf("%d",&w[i][j]);    memset(dp,INF,sizeof dp);dp[0][0][0] = 0;    for(int i=1;i<=n;i++){        if(A[i]) {            for(int j=1;j<=K;j++){                dp[i][A[i]][j] = min(dp[i][A[i]][j],dp[i-1][A[i]][j]);                LL Min = INF;                for(int p = 0;p<=m;p++)                    if(p!=A[i]) Min = min(Min,dp[i-1][p][j-1]);                dp[i][A[i]][j] = min(Min,dp[i][A[i]][j]);            }continue;        }        for(int k=1;k<=K;k++){            for(int j=1;j<=m;j++){                dp[i][j][k] = min(dp[i][j][k],dp[i-1][j][k] + w[i][j]);                LL Min = INF;                for(int p=0;p<=m;p++){                    if(p!=j) Min = min(Min,dp[i-1][p][k-1]);                }                dp[i][j][k] = min(dp[i][j][k],Min+w[i][j]);            }        }    }    LL ans = INF;    for(int i=1;i<=m;i++) ans = min(ans,dp[n][i][K]);    printf("%lld\n",ans==INF?-1:ans);    return 0;}
0 0
原创粉丝点击