洛谷 P1156 垃圾陷阱

2 篇文章 0 订阅

原来奶牛可以吃垃圾(大雾)   题目

题目大意

某奶牛——卡门(难道不是歌剧吗),据说是农夫约翰极其珍视的一条Holsteins奶牛。

它落到“垃圾井”中,“垃圾井”深度为D(2<=D<=100)英尺。

每个垃圾可以用来吃或堆放,堆放垃圾不用花费时间。

知道每个垃圾扔下的时间t(0<t<=1000),以及每个垃圾堆放的高度h(1<=h<=25)和吃进该垃圾能维持生命的时间f(1<=f<=30) ,要求出最早能逃出井外的时间或最长可以存活的时间

奶牛当前体内有足够持续10小时的能量,如果10小时内没有进食就会饿死

题目分析

l[i]表示堆到i高度时奶牛最大的生命值为l[i],对垃圾扔下的时间排序。

从而得到转移方程:
l[j+h[i]]=max(l[j+h[i]],l[j]);
l[j]+=a[i];

代码

#include<cstdio>
#include<cstring>

int t[110],f[110],h[110]; 
int l[1010];//l[i]表示垃圾堆到i高度时奶牛最大的生命值 
int max(int x,int y) { return x>y?x:y; } 

void dfs(int l,int r)//快排,将垃圾扔下来的时间排个序 
{
    int x=l,y=r,m=t[(x+y)/2];
    while(x<=y)
    {
        while(t[x]<m) x++;
        while(t[y]>m) y--;
        if(x<=y)
        {
            int d;
            d=t[x]; t[x]=t[y]; t[y]=d;
            d=f[x]; f[x]=f[y]; f[y]=d;
            d=h[x]; h[x]=h[y]; h[y]=d;
            x++; y--;
        }
    }
    if(x<r) dfs(x,r);
    if(y>l) dfs(l,y);
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    memset(l,0,sizeof(l)); 
    
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d %d",&t[i],&f[i],&h[i]);
        //分别表示垃圾投进井中的时间,能维持卡门生命的时间,能垫高的高度 
    }
    
    dfs(1,m);//习惯了手打快排... 
    
    l[0]=10;//就算卡门不吃垃圾也不堆垃圾都有10天的生命的啦 
	
	//这道题其实就是01背包嘛  
    for(int i=1;i<=m;i++) 
    {
        for(int j=n;j>=0;j--)
        {
            if(t[i]<=l[j])//如果卡门能活到这个垃圾丢下来的时间,那么就可以选择 
            {
                if(j+h[i]>=n)//如果高度达到d,说明奶牛成功的出来了! 
                {
                    printf("%d",t[i]);//输出这个垃圾丢下来的时间 
                    return 0;//既然都得到答案就可以直接退出程序了 
                }
                //选择堆这个垃圾
                l[h[i]+j]=max(l[j],l[h[i]+j]);
                //到达h[i]+j的时候,最大生命值是max(堆上去之后的生命值,原来生命值)的结果,要记住一开始l的初始化 
                
                //选择吃这个垃圾
                l[j]+=f[i];//生命值增长,此时高度不变
            }
        }
    }
    
    printf("%d",l[0]);//存活的最长时间 
    return 0;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值