题目大意:有n个点,由m种颜料,有些点没有涂色,有些点已经涂色了,告诉你每个点涂m种颜色的价格分别是多少,
让你求将这n个点分成k段最少需要多少钱。
思路:动态规划,我们另dp[ i ][ j ][ k ] 表示到i个点为止,分成j段,最后一段的颜色为k的最少值,然后就能很容易地
写出状态转移方程。
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int N=105; 5 const ll inf=0x3f3f3f3f3f3f3f3f; 6 ll dp[N][N][N],c[N],cost[N][N]; 7 int n,m,k; 8 int main() 9 { 10 memset(dp,inf,sizeof(dp)); 11 scanf("%d%d%d",&n,&m,&k); 12 for(int i=1;i<=n;i++) scanf("%lld",&c[i]); 13 for(int i=0;i<=m;i++) dp[0][0][i]=0; 14 for(int i=1;i<=n;i++) 15 { 16 for(int j=1;j<=m;j++) scanf("%lld",&cost[i][j]); 17 } 18 for(int i=1;i<=n;i++) 19 { 20 for(int j=1;j<=k;j++) 21 { 22 for(int u=1;u<=m;u++) 23 { 24 if(c[i] && u!=c[i]) continue; 25 for(int v=0;v<=m;v++) 26 { 27 if(u==v) dp[i][j][u]=min(dp[i][j][u],dp[i-1][j][v]); 28 else dp[i][j][u]=min(dp[i][j][u],dp[i-1][j-1][v]); 29 } 30 if(!c[i]) dp[i][j][u]+=cost[i][u]; 31 } 32 } 33 } 34 ll ans=inf; 35 for(int i=1;i<=m;i++) ans=min(ans,dp[n][k][i]); 36 printf("%lld ",ans==inf? -1:ans); 37 return 0; 38 }