题解报告——垃圾陷阱

题目网址:

https://www.luogu.org/problemnew/show/P1156

题目描述

卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中。“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2<=D<=100)英尺。

卡门想把垃圾堆起来,等到堆得与井同样高时,她就能逃出井外了。另外,卡门可以通过吃一些垃圾来维持自己的生命。

每个垃圾都可以用来吃或堆放,并且堆放垃圾不用花费卡门的时间。

假设卡门预先知道了每个垃圾扔下的时间t(0< t<=1000),以及每个垃圾堆放的高度h(1<=h<=25)和吃进该垃圾能维持生命的时间f(1<=f<=30),要求出卡门最早能逃出井外的时间,假设卡门当前体内有足够持续10小时的能量,如果卡门10小时内没有进食,卡门就将饿死。

看看如此可爱的小奶牛,等待你来拯救哦!!!

那我们来看看这道题的思路

1.首先对于每个掉下的垃圾来说我们都有两种选择:吃或不吃

所以我们可以定一个数组f[i][j]来表示在第 i 个物品掉落时,达到高度 j 所能活到的最大时间

1 struct sd{
2     int time,h,w;
3 }junk[105];
4 const int INF=99999999;
5 int f[105][105];
6 int len,n;

2.找状态转移方程

我们便可以得到两个状态转移方程(当然要判断在活着的前提下)

f[i][j]=max(f[i][j],f[i-1][j]+junk[i].w);--->不吃 

f[i][j]=max(f[i][j],f[i-1][j-junk[i].h]);--->吃掉

 1 f[0][0]=10;
 2 for(int i=1;i<=n;i++)
 3 for(int j=0;j<=len;j++)
 4 {
 5      if(f[i-1][j]>=junk[i].time)
 6      f[i][j]=max(f[i][j],f[i-1][j]+junk[i].w);
 7         
 8       if(j>=junk[i].h)
 9       if(f[i-1][j-junk[i].h]>=junk[i].time)
10       f[i][j]=max(f[i][j],f[i-1][j-junk[i].h]);
11  }
12         

3.查到结果

当我们的 j 达到指定高度时,且当前可存活到的时间点大于第 i 个物品掉落的时间,那这次物品掉落的时间 i 就是最短时间

1 if(j==len&&f[i][j]>=junk[i].time)
2         {
3             printf("%d",junk[i].time);
4             exit(0);
5         }

但如果查询完了都没找到最短时间,那么我们就在再循环一次,这一次我们一遇到垃圾就吃掉,因为知道不可能存活的,所以我们保证到死之前都一直吃。。。

1 int ans=10;
2     for(int i=1;i<=n;i++)
3     {
4         if(ans>=junk[i].time)
5         ans+=junk[i].w;
6         else break;
7     }
8     printf("%d",ans);

最后来看看代码吧。。。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 struct sd{
 5     int time,h,w;
 6 }junk[105];
 7 const int INF=99999999;
 8 int f[105][105];
 9 int len,n;
10 bool cmp(sd a,sd b)
11 {
12     return a.time<b.time;
13 }
14 void dp()
15 {
16     f[0][0]=10;
17     for(int i=1;i<=n;i++)
18     for(int j=0;j<=len;j++)
19     {
20         if(f[i-1][j]>=junk[i].time)
21         f[i][j]=max(f[i][j],f[i-1][j]+junk[i].w);
22         
23         if(j>=junk[i].h)
24         if(f[i-1][j-junk[i].h]>=junk[i].time)
25         f[i][j]=max(f[i][j],f[i-1][j-junk[i].h]);
26         
27         if(j==len&&f[i][j]>=junk[i].time)
28         {
29             printf("%d",junk[i].time);
30             exit(0);
31         }
32     }
33     int ans=10;
34     for(int i=1;i<=n;i++)
35     {
36         if(ans>=junk[i].time)
37         ans+=junk[i].w;
38         else break;
39     }
40     printf("%d",ans);
41 }
42 int main()
43 {
44     scanf("%d%d",&len,&n);
45     for(int i=1;i<=n;i++)
46     scanf("%d%d%d",&junk[i].time,&junk[i].w,&junk[i].h);
47     for(int i=1;i<=n;i++)
48     for(int j=0;j<=len;j++)
49     f[i][j]=-INF;
50     sort(junk+1,junk+1+n,cmp);
51     dp();
52     
53     return 0;
54 }
原文地址:https://www.cnblogs.com/genius777/p/8476360.html