Problem Statement | |||||||||||||
Cat Taro has some trees in his garden. Initially, the i-th tree (0-based index) is height[i] meters tall. Each day the trees grow. For each i, the i-th tree will grow by exactly add[i] meters during each day. Taro wants cut the trees and he has some devices to do that. For each valid i, the i-th device (0-based index) will cut any chosen tree with height greater thandevice[i] meters to exactly device[i] meters. At the end of each day, Taro can choose any (possibly empty) subset of trees and cut them. There are two restrictions:
You are given the vector <int>s height, add and device, and an int time. Return the smallest possible sum of the heights of the trees after time days (i.e.,time iterations of "the trees grow and then Taro cuts some of them"). | |||||||||||||
Definition | |||||||||||||
| |||||||||||||
Limits | |||||||||||||
| |||||||||||||
Constraints | |||||||||||||
- | height will contain between 1 and 150 elements, inclusive. | ||||||||||||
- | height and add will contain the same number of elements. | ||||||||||||
- | device will contain between 1 and 150 elements, inclusive. | ||||||||||||
- | Each element of height, add and device will be between 0 and 10,000, inclusive. | ||||||||||||
- | time will be between 1 and 150, inclusive. | ||||||||||||
Examples | |||||||||||||
0) | |||||||||||||
| |||||||||||||
1) | |||||||||||||
| |||||||||||||
题意:给出n颗树的高度h以及生长速度a,并给出m个设备的性能d,求最终t天后的n颗树的最小树长和。
意识:小数据加上求最小值不难想到是网络流中的最小费用流。
题解:最小费用流或者DP,这里仅仅给出最小费用流的做法。
下面给出做法。
先对题意进行转化:
最终答案对于每棵树实际上只用考虑那棵树被砍的最后一下即可(即前面不管被砍多少次,都不会影响最后一次砍的结果)即在t天以后对于每棵树i,假设它最后一下是在ti'天被砍下的,那么仅仅对于这颗树的长度 Li=(t-ti')*ai+di;另外,还有一种特殊情况,如果他一下都没被砍到,那么Li=ai*t+di。
那么ΣLi就是答案。
下面讲建图:
节点的个数一共2(起点S终点T)+1(虚拟节点G,特判不砍的情况)+树的个数+时间t+设备的个数。
在示例图中,对于每种边都标上了两个数字,左边是限制limit,右边是代价cost.
n就是tree树的个数。在这个基础上跑一发最小费用流就能得到答案。
下面只给出建图的代码://代码中n1为示例图中的n,代码中n实际为总节点的个数
int getNumber(vector <int> height, vector <int> add, vector <int> device, int time)
{
int n1=height.size();
int m=device.size();
int av=n1;
int bv=av+time;
int sv=bv+m;
int tv=sv+1;
int gv=tv+1;
n=gv+1;
for(int i=0;i<n1;i++)add_edge(sv,i),add_edge(i,gv,height[i]+add[i]*time);
for(int i=0;i<n1;i++)
{
for(int j=0;j<time;j++)add_edge(i,av+j,add[i]*j);
}
for(int i=0;i<time;i++)
{
for(int j=0;j<m;j++)add_edge(av+i,bv+j);
}
for(int i=0;i<m;i++)add_edge(bv+i,tv,device[i],time);
add_edge(gv,tv,0,n1);
return min_cost_flow(sv,tv,n1);
}