首页 > 其他分享 >[刷题笔记] LuoguP1156 垃圾陷阱

[刷题笔记] LuoguP1156 垃圾陷阱

时间:2023-08-05 14:34:57浏览次数:51  
标签:投放 trush int 笔记 垃圾 LuoguP1156 trash 转移 刷题

Problem

Description

题目描述了几个状态,我们来理顺一下:

一头牛掉进了坑里,农夫会在几个时段向下扔垃圾,牛初始可以撑10h,对于每一个垃圾,牛可以:

  • 把它堆起来,一旦垃圾堆的高度超过\(h\),她就可以爬出来

  • 吃掉它垃圾好吃吗,并且获得能量值

需要注意的是,牛可以撑到下一次垃圾投放的标准是还能活着的时间\(t\) 大于等于下次垃圾投放的时间\(t'\),也就是说,每两次垃圾投放会消耗牛\(t_2-t_1\)生命(\(t_2\)代表第二题垃圾投放时间,\(t_1\)代表第一次垃圾投放时间)

如果牛能出去,就输出最早什么时候能爬出,也就是最后一次处理垃圾的投放时间(牛处理垃圾是瞬间的)

Solution

一股强烈的背包气息

我们发现对于每次垃圾投放,牛需要做出如下决策:

  • 把它堆在垃圾堆上
  • 吃掉

和普通的背包不同,本题需要的参数有:

  • 牛的生命值
  • 垃圾堆高度
  • 牛能爬出去的时间
  • 如果不能爬出去,记录牛最多能活多久
    参数好多!总不能全都记录,最后MLE吧(

我们再来简化状态。
首先,牛能爬出去的时间是最后一次处理垃圾的时间,而垃圾投放下去牛可以瞬间处理完,所以也就是最后一次垃圾投放牛做决策的时间。

其次,垃圾投放题目并不保证是按照时间顺序输入的,我们需要排序。

但还是没有思路......

我们不妨换个思路,\(f\)数组里只记录牛在多少垃圾投放的时候,垃圾堆高度为多少的时候的最大生命值,因为我们首先要确保牛能出去,再确保利用的垃圾最毕竟垃圾不好吃qwq

这样记录,我们最后只需要判断在出口高度下牛有没有生命值就可以,如果发现有生命值则直接输出最先找到牛有生命值时的垃圾编号,输出它投放的时间即可。

如果牛很惨没出去,我们也只需要输出牛最大能有生命值的时间即可,也就是最大的\(f_{i,j}\),别忘了我们记录的生命值就是时间呀。

需要注意只有牛可以在下一次垃圾投放时活下来我们才转移,也就是\(f_{i-1,j}-trush_{i}.t >=0\)时,这里的\(trush_{i}.t\)表示从小到大排好序的第\(i\)个垃圾投放时间。

我们转移需要进行两次:

  • 吃掉该垃圾的转移

  • 把垃圾堆起来的转移

我们不能和普通背包一样两种转移合并到一起,本题有两个参数,我们需要确保牛如果在下一次做出该决策她能活着,有的时候可能只能进行一种转移。(当然两个转移是并列的,如果满足当然可以进行两次转移)

因此,我们有两个状态转移方程,分别对应两种决策,如下:
\(f_{i,j}=max(f_{i,j},f_{i-1,j}+trush_i.live(f_{i-1,j} >= trush_i.t)\)

\(f_{i,j}=max(f_{i,j},f_{i-1,j-trush_i.h} (j>=trush_i.h,f_{i-1,j-trush_i.h}>=trush_i.t)\)

Explanation:第一个状态转移方程是吃掉垃圾时的决策,由于下次吃掉垃圾对高度无影响,所以\(j\)不变;第二个状态转移方程是下一次把垃圾堆起来的决策,由于下次堆垃圾对高度有影响,所以上一次高度需要取\(j-trush_{i}.h\),也就是上一次的高度等于本次高度减去本次的垃圾。此外如果想要堆起来必须满足枚举的垃圾堆的高度大于等于垃圾高度,否则会越界。

(PS:需要注意我们每次都是在做现在的决策,之所以说上次下次可能更好理解,需要注意。)

另外,我们需要对\(f\)数组进行初始化,初始化令\(f_{0,0}=10\)即可,因为显然在没有垃圾投放的时候牛初始能撑10h,注意理解题意。

本题的重难点在于如何判断能否转移,能否转移的条件是什么?如何设计状态?

至此,本题得解,代码如下:

Code

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define N 10010
using namespace std;
int d,g;
struct Node
{
    int t,c,h;
}trash[N];
bool cmp(Node a,Node b)
{
    return a.t < b.t;
}
int f[N][N];
int maxn = -1;
int main()
{
    scanf("%d%d",&d,&g);
    for(int i=1;i<=g;i++)
    {
        scanf("%d%d%d",&trash[i].t,&trash[i].c,&trash[i].h);
    }
    f[0][0]  = 10;
    sort(trash+1,trash+g+1,cmp);
    for(int i=1;i<=g;i++)
    for(int j=0;j<=d;j++)
    {
        if(f[i-1][j]>=trash[i].t)
            f[i][j]=max(f[i][j],f[i-1][j]+trash[i].c);
        if(j>=trash[i].h&&f[i-1][j-trash[i].h]>=trash[i].t)
            f[i][j]=max(f[i][j],f[i-1][j-trash[i].h]);
    }
     int maxh=0;
    int maxt=0;
    int i;
    for(i=1;i<=g;i++)
    {
        for(int j=0;j<=d;j++)
        {
            if(f[i][j]-trash[i].t>=0)
                maxh=max(maxh,j);
            maxt=max(maxt,f[i][j]);
        }
        if(maxh==d)
            break;
    }
    if(maxh==d)
    {
        cout<<trash[i].t<<endl;
    }
    else
        cout<<maxt<<endl;
    return 0;
}

标签:投放,trush,int,笔记,垃圾,LuoguP1156,trash,转移,刷题
From: https://www.cnblogs.com/SXqwq/p/17607733.html

相关文章

  • ZROI 学习笔记之字符串串
    嘿嘿嘿……字符串……我的串串……都别催!!!等我有时间了例题和详细讲解都会补回来的!!!一些约定在此博客中,为更方便的表示字符串的相关信息,我们使用如下记法:字符集:一般记作\(\Sigma\),是一个包含可能的所有输入字符的、建立了全序关系的集合,具体视题目而定。一般是一个泛性的概念......
  • 矩阵乘法 笔记
    众所周知,数是可以进行加减乘除的,那矩阵为啥不可以呢?假设现在我们有两个矩阵\(A\)和\(B\),矩阵大小分别为\(n\timesm\)和\(x\timesy\),矩阵元素对\(mod\)取模。基本运算矩阵加法令\(A+B=C\)。要求:\(n=x\)并且\(m=y\)。其实很简单,就是一一对应着加就行,即......
  • 二维数组花式遍历(旋转,螺旋) [labuladong-刷题打卡 day5]
    矩阵旋转48.旋转图像难点主要在于:用翻转和镜像处理逆反和旋转,和逆转单词一样“难者不会,会者不难”,思路简单镜像的坐标对应关系处理语言特性的利用,不同语言有不同api,实际代码中会有很大不同,但思想一致如果确定矩阵维数,通过线性代数应该可以直接计算答案...classSolution......
  • openGauss学习笔记-31 openGauss 高级数据管理-索引
    openGauss学习笔记-31openGauss高级数据管理-索引索引是一个指向表中数据的指针。一个数据库中的索引与一本书的索引目录是非常相似的。索引可以用来提高数据库查询性能,但是不恰当的使用将导致数据库性能下降。建议仅在匹配如下某条原则时创建索引:经常执行查询的字段。在连......
  • 【学习笔记】博弈论
    SG函数与SG定理公平组合游戏公平组合游戏满足以下条件:两个玩家参与游戏,轮流操作。游戏以某个玩家不能操作未结束,且不能操作的玩家失败,游戏不含平局。游戏的操作与玩家无关,只与当前的状态有关。游戏状态不会重复出现,若将状态设为点,将一次操作对状态的改变设为有向......
  • Spring Cloud 笔记
    单体应用存在的问题随着业务的发展,开发变得越来越复杂。修改、新增某个功能,需要对整个系统进行测试、重新部署。一个模块出现问题,很可能导致整个系统崩溃。多个开发团队同时对数据进行管理,容易产生安全漏洞。各个模块使用同一种技术进行开发,各个模块很难根据实际情况选择更......
  • [刷题笔记] Luogu P2014 [CTSC1997] 选课
    ProblemSolution我们发现本题中有好多主从关系,即要想取用一个儿子必须先取用她的父亲。构成了一个森林,处理不便。有个小技巧,就是将0号节点参与建树,最后所求节点数就变成了\(m+1\),且把森林变成了一棵树。然后如何处理呢?再次理解题意,我们发现,我们每次的决策是是否取用儿子,取用......
  • 前端学习笔记202305学习笔记第二十天-vue3.0-插槽自定义操作列
    ......
  • 前端学习笔记202307学习笔记第六十二天-react性能优化-5
        ......
  • 前端学习笔记202306学习笔记第四十二天-async函数的返回值2
         ......