CuttingGrass
Task:
给定农场里的
n
株草,每种草都有自己的初始高度
求将这些草的高度之和变为小于等于H的最短时间,无法完成输出-1。(
n<=50,grow[i]<=1,000,000
)
Solution:
刚看到这题时其实是挺scary的(官方题解用词),答案没有一个明显的上界。但是仔细一想便能发现答案不会超过
n
,因为重复地剪同一株草是没有意义的。
然后我们枚举这个
同样的,如果我们在第
i
个时刻剪掉了第
显然,
grow[i]
小的
i
应当先剪掉,于是我们可以按照
然后,这就变成了一个从
n
个数里面选
注:话说这里写挫了,dp数组与枚举的
t
是无关的,可以另行处理出来,复杂度即为
struct Node{
int p,g;
bool operator <(const Node &a)const{
return g<a.g;
}
}A[M];
int dp[M];
class CuttingGrass {
public:
void check(int &a,int b){
if(a==-1||a<b)a=b;
}
int theMin(vector <int> init, vector <int> grow, int H) {
int n=init.size();
for(int i=0;i<n;i++)
A[i+1].p=init[i],A[i+1].g=grow[i];
sort(A+1,A+n+1);
for(int t=0;t<=n;t++){
memset(dp,-1,sizeof(dp));
int tot=0;
for(int i=1;i<=n;i++)
tot+=A[i].p+A[i].g*t;
dp[0]=0;
for(int i=1;i<=n;i++)
for(int j=t-1;j>=0;j--)
if(dp[j]!=-1)check(dp[j+1],dp[j]+A[i].p+(j+1)*A[i].g);
if(tot-dp[t]<=H)return t;
}
return -1;
}
};