zoukankan      html  css  js  c++  java
  • Luogu P1156 垃圾陷阱 【dp】By cellur925

    题目传送门

    这题...看上去浓浓的背包气息...但是并不好设计状态啊emmm。

    我们考虑可能成为状态的量:高度、血量、时间、物品。看数据范围也猜到应该大概是个二维dp了w。

    正确的状态设计之一:设$f[i][j]$表示用到第$i$个物品,当前高度为$j$的最大血量。为什么用这个状态,因为写转移比较好写==

    每个物品一定在它扔下的那时就被处理的,对于每个物品,每一时间我们有两种决策:堆起来和吃掉。

    • 堆起来:首先在这个时刻奶牛一定是活着的(血量>=0),而且之前的高度一定大于等于0我们要注意检验它是否活着是要把两个相邻物品的时间差减去(这段时间没有进食)。那么便有转移:

       $f[i][j]$=$max${$f[i-1][j-rub[i].h]$-$rub[i].tim$+$rub[i-1].tim$}

    • 吃掉它:同上,这时奶牛也必须活着。

       $f[i][j]$=$max${$f[i-1][j]$-$rub[i].tim$+$rub[i-1].tim$+$rub[i].val$}

    我们的dp部分就结束了。

    之后就是赋初值的细节,开始$f$数组是负无穷的,且有$f[0][0]=10$。

    在处理答案方面,当我们dp时遇到一个与井同高的时刻,我们就可以判断它是否能作为答案。

    如果无解,那么答案就由$f[i][j]$+$rub[i].tim$来寻找最大值。

    Code

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 
     5 using namespace std;
     6 
     7 int well_h,n,ans;
     8 bool flag;
     9 int f[200][500]; 
    10 struct rubbish{
    11     int tim,val,h;
    12 }rub[500];
    13 
    14 bool cmp(rubbish a,rubbish b)
    15 {
    16     return a.tim<b.tim;
    17 }
    18 
    19 int main()
    20 {
    21     scanf("%d%d",&well_h,&n);
    22     for(int i=1;i<=n;i++)
    23         scanf("%d%d%d",&rub[i].tim,&rub[i].val,&rub[i].h);
    24     sort(rub+1,rub+1+n,cmp);
    25     memset(f,128,sizeof(f));
    26     f[0][0]=10;
    27     for(int i=1;i<=n;i++)
    28         for(int j=0;j<=well_h;j++)
    29         {
    30             if(f[i-1][j]-rub[i].tim+rub[i-1].tim>=0)
    31                 f[i][j]=max(f[i][j],f[i-1][j]-rub[i].tim+rub[i-1].tim+rub[i].val);
    32             if(f[i-1][j-rub[i].h]-(rub[i].tim-rub[i-1].tim)>=0&&j-rub[i].h>=0)
    33             {
    34                 f[i][j]=max(f[i][j],f[i-1][j-rub[i].h]-(rub[i].tim-rub[i-1].tim));
    35                 if(j==well_h){printf("%d",rub[i].tim),flag=1;return 0;}
    36             }                
    37         }
    38     if(!flag)
    39         for(int i=0;i<=n;i++)
    40             for(int j=0;j<=well_h;j++)
    41                 ans=max(ans,f[i][j]+rub[i].tim);
    42     printf("%d
    ",ans);
    43     return 0;
    44 }
    View Code

    细节:dp题目注意从0开始枚举的情况。

  • 相关阅读:
    nessus 安装
    firefox SSL_ERROR_RX_RECORD_TOO_LONG burpsuit 报错 解决方案
    Vmware 15 新建虚拟机黑屏
    esp8266 IOT Demo 固件刷写记录
    elk + suricata 实验环境详细安装教程
    停更申明
    求二叉树的深度
    方差
    链表的基本排序
    正态分布及3Sigma原理
  • 原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9744577.html
Copyright © 2011-2022 走看看