有 n n n棵草,第 i i i棵草的高度为 w h [ i ] . w wh[i].w wh[i].w,在每一轮中,草都会长高 w h [ i ] . h wh[i].h wh[i].h,有一个人来剪草,当他减掉某棵草时,他的高度就变为 0 0 0,你的任务是,用最短的时间使得所有的草高度总和不超过 m m m,如果不能则输出 − 1 -1 −1
输入
输入样例#1
3 16
5 8 58
2 1 1
输入样例#2
2 58
5 8
2 1
输入样例#3
2 0
5 8
5 1
输出
输出样例#1
1
输出样例#2
0
输出样例#3
-1
思路
D
P
DP
DP
用
f
[
i
]
[
j
]
f[i][j]
f[i][j]代表前
i
i
i棵草,减
j
j
j次,最少的高度
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
struct whw
{
int w,h;
}wh[2025];
int f[2005][2005];
int n,m,k,sum;
bool Nwh(whw i,whw j)
{return i.h<j.h;}
int main()
{
freopen("grass.in","r",stdin);
freopen("grass.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%d",&wh[i].w);
for(int i=1;i<=n;++i)
scanf("%d",&wh[i].h);
sort(wh+1,wh+n+1,Nwh);
for(int i=0;i<=n;++i)
{
for(int j=1;j<=n;++j)
for(int k=1;k<=i;++k)
f[j][k]=1e9;
for(int j=1;j<=n;++j)f[j][0]=f[j-1][0]+wh[j].w+wh[j].h*i;//赋初值(不剪)
for(int j=1;j<=n;++j)
for(int k=1;k<=i;++k)
f[j][k]=min(f[j-1][k]+wh[j].w+wh[j].h*i,f[j-1][k-1]+wh[j].h*(i-k));//从剪与不剪中选取最大的
if(f[n][i]<=m){printf("%d",i);return 0;}
}
printf("-1");
fclose(stdin);
fclose(stdout);
}