Coloring Trees

56 篇文章 1 订阅

CodeForces – 711C

https://www.luogu.com.cn/problem/CF711C

题目描述

ZS the Coder and Chris the Baboon has arrived at Udayland! They walked in the park where nn trees grow. They decided to be naughty and color the trees in the park. The trees are numbered with integers from 11 to nn from left to right.

Initially, tree ii has color c_{i}ci​ . ZS the Coder and Chris the Baboon recognizes only mm different colors, so 0<=c_{i}<=m0<=ci​<=m , where c_{i}=0ci​=0 means that tree ii is uncolored.

ZS the Coder and Chris the Baboon decides to color only the uncolored trees, i.e. the trees with c_{i}=0ci​=0 . They can color each of them them in any of the mm colors from 11 to mm . Coloring the ii -th tree with color jj requires exactly p_{i,j}pi,j​ litres of paint.

The two friends define the beauty of a coloring of the trees as the minimum number of contiguous groups (each group contains some subsegment of trees) you can split all the nn trees into so that each group contains trees of the same color. For example, if the colors of the trees from left to right are 2,1,1,1,3,2,2,3,1,32,1,1,1,3,2,2,3,1,3 , the beauty of the coloring is 77 , since we can partition the trees into 77 contiguous groups of the same color : {2},{1,1,1},{3},{2,2},{3},{1},{3}2,1,1,1,3,2,2,3,1,3 .

ZS the Coder and Chris the Baboon wants to color all uncolored trees so that the beauty of the coloring is exactly kk . They need your help to determine the minimum amount of paint (in litres) needed to finish the job.

Please note that the friends can’t color the trees that are already colored.

输入格式

The first line contains three integers, nn , mm and kk ( 1<=k<=n<=1001<=k<=n<=100 , 1<=m<=1001<=m<=100 ) — the number of trees, number of colors and beauty of the resulting coloring respectively.

The second line contains nn integers c_{1},c_{2},…,c_{n}c1​,c2​,…,cn​ ( 0<=c_{i}<=m0<=ci​<=m ), the initial colors of the trees. c_{i}ci​ equals to 00 if the tree number ii is uncolored, otherwise the ii -th tree has color c_{i}ci​ .

Then nn lines follow. Each of them contains mm integers. The jj -th number on the ii -th of them line denotes p_{i,j}pi,j​ ( 1<=p_{i,j}<=10^{9}1<=pi,j​<=109 ) — the amount of litres the friends need to color ii -th tree with color jj . p_{i,j}pi,j​ ‘s are specified even for the initially colored trees, but such trees still can’t be colored.

输出格式

Print a single integer, the minimum amount of paint needed to color the trees. If there are no valid tree colorings of beauty kk , print -1−1 .

题意翻译

题意:

有 nn 棵树, mm 种颜料,要求现在要给这些树涂上颜料,最后涂成 kk 段(连续颜色相同划为一段如 22 , 11 , 11 , 11 , 33 , 22 , 22 , 33 , 11 , 33 是77段),有些树已经涂了,则不涂了只能涂一次,输入nn个数(每个数为00~mm),0表示还没有涂,11~mm表示已经涂了哪种颜料。接下来输入 nn 行 mm 列,表示每棵树涂成每种颜色所要的颜料量。现在要把所有树都涂上颜料涂成 kk 段,求最少要用的颜料量

翻译 byby @Happynewyear

输入输出样例

输入 #1复制

3 2 2
0 0 0
1 2
3 4
5 6

输出 #1复制

10

输入 #2复制

3 2 2
2 1 2
1 3
2 4
3 5

输出 #2复制

-1

输入 #3复制

3 2 2
2 0 0
1 3
2 4
3 5

输出 #3复制

5

输入 #4复制

3 2 3
2 1 2
1 3
2 4
3 5

输出 #4复制

0

说明/提示

In the first sample case, coloring the trees with colors 2,1,12,1,1 minimizes the amount of paint used, which equals to 2+3+5=102+3+5=10 . Note that 1,1,11,1,1 would not be valid because the beauty of such coloring equals to 11 ( {1,1,1}1,1,1 is a way to group the trees into a single group of the same color).

In the second sample case, all the trees are colored, but the beauty of the coloring is 33 , so there is no valid coloring, and the answer is -1−1 .

In the last sample case, all the trees are colored and the beauty of the coloring matches kk , so no paint is used and the answer is 00 .


思路:一道线性dp的好题目。

定义:dp[i][j][k]为前i个点分成j段并且最后一段颜色是k的最小代价

当第i个点是有颜色的。

如果和前面一个点颜色一致,dp[i][j][l]=min(dp[i][j][l],dp[i-1][j][l]);

如果和前面一个点的颜色不一致,dp[i][j][col[i]]=min(dp[i][j][col[i]],dp[i-1][j-1][l]);

如果第i个点是无颜色的

如果涂上和前面一个点不一致的颜色。dp[i][j][l]=min(dp[i][j][l],d[i-1][j-1][p]+w[i][l]);

如果涂上和前面一个点一致的颜色。dp[i][j][l]=min(dp[i][j][l],dp[i-1][j][p]+w[i][l]);

注意dp的初始化开大一点。

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<cstdio>
#include<algorithm>
#define inf 0x7f7f7f7f7f7f
using namespace std;
typedef long long LL;
const int maxn=200;
LL dp[maxn][maxn][maxn];//dp[i][j][k]:前i棵树分成j段且最后一段颜色为k时的最小花费 
LL w[maxn][maxn];
LL col[maxn];
LL n,m,k;
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  cin>>n>>m>>k;
  for(LL i=1;i<=n;i++) cin>>col[i];
  for(LL i=1;i<=n;i++){
  	for(LL j=1;j<=m;j++)
  		cin>>w[i][j];
  }
  memset(dp,inf,sizeof(dp));
  if(col[1]) dp[1][1][col[1]]=0;
  else{
  	for(LL i=1;i<=m;i++) dp[1][1][i]=w[1][i];	
  }
  for(LL i=2;i<=n;i++){
    for(LL j=1;j<=i&&j<=k;j++){
    	if(col[i]){//第i个点有颜色
	        for(LL l=1;l<=m;l++){
	        	if(col[i]==l){
	        		dp[i][j][l]=min(dp[i][j][l],dp[i-1][j][l]);//同样颜色为连续一段 
				}
				else dp[i][j][col[i]]=min(dp[i][j][col[i]],dp[i-1][j-1][l]);//不同颜色为新开一段 
			}
		}
		else{
			for(LL l=1;l<=m;l++){
				for(LL p=1;p<=m;p++){
					if(l==p) dp[i][j][l]=min(dp[i][j][l],dp[i-1][j][p]+w[i][l]);//一样颜色就连续一段 
					else dp[i][j][l]=min(dp[i][j][l],dp[i-1][j-1][p]+w[i][l]);//不一样颜色就另开一段 
				}
			}
		} 
	}	
  }
  	LL ans=inf;
	if(col[n]) ans=dp[n][k][col[n]];
	else {
		for(LL l=1;l<=m;l++){
			ans=min(ans,dp[n][k][l]);
		}
	} 
	if(!(ans<inf)) cout<<"-1"<<endl;
	else cout<<ans<<endl;
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值