P1156 垃圾陷阱

题意:给出一只困在井里的动物,给出这只动物目前能够存活时间为10小时

    给出n个垃圾(竟然吃辣鸡?)每个辣鸡有投放的时间点,吃这个辣鸡能获得的体力,堆放这个辣鸡能获得的高度

    问:假如能逃出这个井,最少花多长时间?

      假如不能逃出,最长存活时间为?

思路:首先,我们要将垃圾投放的时间进行从小到大排序

     那么,排完序之后,我们肯定能够想到的一步是,第k个垃圾是要用来吃还是用来堆

        所以,我们就是要根据这一步来列dp

          那么如何列呢,我们要想出一种无后效性的解法

            因为垃圾按时间排序,我们就要得出到达某个垃圾时的最优情况,然后在这个垃圾的最优情况下,继续处理下一个垃圾

              那么如何才能使前后两个垃圾建立联系呢

                自然是从题目给出的信息来找联系,题目中给出了高度,时间,吃垃圾获得体力(显然不可能用这个)

   那么能通过时间嘛?不行,时间给出的数据太大,会超时

   于是,剩下的只有高度了,题目中高出的高度的上限是100,所以可以想想如何做

      所以,开了上帝视角的我,得出这样一个结论:可以开一个第一维记录到了哪个垃圾,第二维记录在这个垃圾的情况下,枚举(0,上限)的高度

        那么dp的时候有两种情况

          第一种:把垃圾吃掉,想要吃掉垃圾,就要保证能活到投掷这个垃圾的时间点

          第二种:堆砌垃圾,要堆砌垃圾,也要活到投掷垃圾的时间点,并且之前的高度不能为负数

          然后,假如在投放这个垃圾的时候,已经能够到达顶点,就直接输出投掷这个垃圾的时间即可(表示在这个时间就可以逃出来)

          假如一直没有出来,就表明出不来,那么最后再枚举一遍,能存活的最长时间即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e3+10;
 4 const int inf=0x3f3f3f3f;
 5 int f[101][1001];
 6 struct node
 7 {
 8     int x,t,h;
 9 }a[maxn];
10 int cmp(node a,node b)
11 {
12     return a.x<b.x;
13 }
14 int main()
15 {
16     int n,m;
17     int tmp=10;
18     scanf("%d%d",&n,&m);
19     for(int i=1;i<=m;i++){
20         scanf("%d%d%d",&a[i].x,&a[i].t,&a[i].h);
21     }
22     sort(a+1,a+m+1,cmp);
23     memset(f,-inf,sizeof(f));
24     f[0][0]=10;
25     a[0].x=a[0].t=a[0].h=0;
26     int fl=0;
27     for(int i=1;i<=m;i++){
28         for(int j=0;j<=n;j++){
29             if(f[i-1][j]-a[i].x+a[i-1].x>=0) {
30                // 把垃圾吃掉,想要吃掉垃圾,就要保证能活到投掷这个垃圾的时间点
31                 f[i][j]=max(f[i][j],f[i-1][j]-a[i].x+a[i-1].x+a[i].t);
32             }
33            //堆砌垃圾,要堆砌垃圾,也要活到投掷垃圾的时间点,并且之前的高度不能为负数
34             if (f[i-1][j-a[i].h]-a[i].x+a[i-1].x>=0&&j-a[i].h>=0) {
35                 f[i][j]=max(f[i][j],f[i-1][j-a[i].h]-a[i].x+a[i-1].x);
36                 if(j==n){
37                     printf("%d\n",a[i].x);
38                     fl=1;
39                     return 0;
40                 }
41             }
42         }
43     }
44     int ans=0;
45     if(!fl){
46         for(int i=0;i<=m;i++)
47             ans=max(ans,f[i][0]+a[i].x);
48         printf("%d\n",ans);
49     }
50     return 0;
51 }
View Code

 

posted @ 2020-03-27 11:51  古比  阅读(114)  评论(0编辑  收藏  举报