原来奶牛可以吃垃圾(大雾) 题目
题目大意
某奶牛——卡门(难道不是歌剧吗),据说是农夫约翰极其珍视的一条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;
}