SSL P2394 剪草

目录:

题目:

剪草 题目

题意:

有个穷b,他买不起除草机,只能用剪刀来剪,现在问我们,他最早在什么时候可以达成所有草的总高度<=要求高度

分析:

动态规划是正解,不过不算纯正的动归,有贪心的成分
因为长得快的草如果先剪,那很快就会长高,如果先剪长得慢的草,那高度就增长慢一些,所以应先割长得慢的草。如果剪了n次还没有达到目标,那么永远也不会达到目标。
所以先将生长速度排序,然后动归
f[j,k]表示前j棵草剪了k次的总最小高度
f[j,0]要预处理
对于每棵草和每次剪草,可以考虑剪这棵草和不剪这棵草。剪则总高度= f[j1,k1]+g[i](ik) f [ j − 1 , k − 1 ] + g [ i ] ∗ ( i − k ) ,不剪则= f[j1,k]+a[i]+g[i]i f [ j − 1 , k ] + a [ i ] + g [ i ] ∗ i
还有最后别忘了输出-1

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#define LL long long
using namespace std;
inline LL read() {
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
    return d*f;
}
struct node{
    int g,grow;
}x[51];
int f[51][51];
bool cmp(node a,node b)
{
    return a.grow<b.grow;
}
int min(int a,int b)
{
    return a<b? a:b;
}
int main()
{
/*  freopen("grass.in","r",stdin);
    freopen("grass.out","w",stdout);*/
    int n=read(),h=read();
    for(int i=1;i<=n;i++) x[i].g=read();
    for(int i=1;i<=n;i++) x[i].grow=read();
    sort(x+1,x+1+n,cmp);
    for(int i=0;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            f[j][0]=f[j-1][0]+x[j].g+x[j].grow*i;
            for(int k=1;k<=i;k++)
              f[j][k]=99999999;
        }
        for(int j=1;j<=n;j++)
          for(int k=1;k<=i;k++)
            f[j][k]=min(f[j-1][k]+x[j].g+x[j].grow*i,f[j-1][k-1]+x[j].grow*(i-k));
        if(f[n][i]<=h) {printf("%d",i);return 0;}
    }
    printf("-1");
    fclose(stdin);
    fclose(stdout);
    return 0;
} 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值