题目链接

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

方法1

分析

将已经爬的高度看作背包容积,最大剩余血量看作价值,\(f[i][j]\)表示吃完第\(i\)个垃圾,爬到\(j\)高度的最大剩余血量

\(f[i][j+h[i]]=max(f[i][j+h[i]],f[i-1][j]-(t[i]-t[i-1]))\)

\(f[i][j]=max(f[i][j],f[i-1][j]+c[i]-(t[i]-t[i-1]))\)

当然还要判断能否撑到下一个垃圾的到来,以及判断是否已经爬出了陷阱

如果不能爬出,显然将垃圾全部吃完是最优的,因为垃圾全用来吃了并且没撑到下一个时刻,所以\(ans=max(ans,f[i][0]+t[i])\)

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <cstdlib>
#include <iostream>
#define ll long long
#define ri register int
using std::min;
using std::max;
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while(!isdigit(c=getchar()))ne=c=='-';
x=c-48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
x=ne?-x:x;return ;
}
const int maxn=1005;
const int inf=0x7fffffff;
int f[maxn][105];
bool e[maxn];
int l,m,n;
struct Tra{
int t,c,h;
bool operator <(const Tra &b)const{
return t==b.t?c>b.c:t<b.t;
}
}tra[maxn];
int main(){
int dta,h,ans=10;
read(l),read(n);
for(ri i=1;i<=n;i++){
read(tra[i].t),read(tra[i].c),read(tra[i].h);
}
std::sort(tra+1,tra+1+n);
memset(f,-1,sizeof(f));
f[0][0]=10;
for(ri i=1;i<=n;i++){
h=tra[i].h;
dta=tra[i].t-tra[i-1].t;
for(ri j=l;j>=0;j--){
if(f[i-1][j]==-1||f[i-1][j]<dta)continue;
if(j+h>=l){
printf("%d\n",tra[i].t);
return 0;
}
f[i][j+h]=max(f[i-1][j]-dta,f[i][j+h]);
f[i][j]=max(f[i-1][j]+tra[i].c-dta,f[i][j]);
}
if(f[i][0]!=-1)ans=max(ans,f[i][0]+tra[i].t);
/*注意加特判*/
}
printf("%d\n",ans);
return 0;
}

方法2

分析

刚刚的方法一点也不背包,我们按着01背包套路把它变成一维的,\(f[j]\)表示爬到了高度\(j\)总共加上的最大血量.

\(f[j+h[i]]=max(f[j+h[i]],f[j])\)

\(f[j]+=c[i]\)

按照套路,为了使\(j+h[i]\)这个状态在本阶段中不再出现,我们倒序枚举高度

代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#define ll long long
#define ri register int
using std::min;
using std::max;
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while(!isdigit(c=getchar()))ne=c=='-';
x=c-48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
x=ne?-x:x;return ;
}
const int maxn=1005;
const int inf=0x7ffffff;
int m,n;
struct Tra{
int t,c,h;
bool operator <(const Tra &b)const{
return t<b.t;
}
}tr[maxn];
int f[maxn];
int main(){
read(m),read(n);
for(ri i=1;i<=n;i++){
read(tr[i].t),read(tr[i].c),read(tr[i].h);
}
std::sort(tr+1,tr+1+n);
memset(f,-1,sizeof(f));
f[0]=10;
for(ri i=1;i<=n;i++){
for(ri j=m;j>=0;j--){
if(f[j]>=tr[i].t){
if(j+tr[i].h>=m){
printf("%d\n",tr[i].t);
return 0;
}
f[j+tr[i].h]=max(f[j+tr[i].h],f[j]);
f[j]+=tr[i].c;
}
}
}
printf("%d\n",f[0]);
return 0;
}

luogu1156垃圾陷阱题解--背包DP的更多相关文章

  1. [luogu1156]垃圾陷阱_动态规划_背包dp

    垃圾陷阱 luogu-1156 题目大意:Holsteins在距离地面D英尺的地方,FJ间隔时间ti会往下扔第i个垃圾.Holsteins对待每一个垃圾都会选择吃掉或者垫高.Holsteins有10个 ...

  2. 垃圾陷阱洛谷dp

    题目描述 卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中.“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2<=D<=100)英尺. 卡门想把垃圾堆起来,等到 ...

  3. 洛谷P1156 垃圾陷阱【线性dp】

    题目:https://www.luogu.org/problemnew/show/P1156 题意: 每一个垃圾投放时间是t,可以堆的高度是h,如果吃掉可以增加的生命值是f. 给定g个垃圾,初始生命值 ...

  4. 洛谷 P1156 垃圾陷阱 题解

    题目传送门 dp+排序+01背包 就完事了??? 貌似就是这样的 代码: //dp 排序 01背包 #include<iostream> #include<cstdio> #i ...

  5. [bzoj2287]消失之物 题解(背包dp)

    2287: [POJ Challenge]消失之物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1138  Solved: 654[Submit][ ...

  6. 【bzoj5018】[Snoi2017]英雄联盟 背包dp

    题目描述 正在上大学的小皮球热爱英雄联盟这款游戏,而且打的很菜,被网友们戏称为「小学生」.现在,小皮球终于受不了网友们的嘲讽,决定变强了,他变强的方法就是:买皮肤!小皮球只会玩N个英雄,因此,他也只准 ...

  7. 【bzoj1222】[HNOI2001]产品加工 背包dp

    题目描述 某加工厂有A.B两台机器,来加工的产品可以由其中任何一台机器完成,或者两台机器共同完成.由于受到机器性能和产品特性的限制,不同的机器加工同一产品所需的时间会不同,若同时由两台机器共同进行加工 ...

  8. 【bzoj3687】简单题 背包dp+STL-bitset

    题目描述 小呆开始研究集合论了,他提出了关于一个数集四个问题:1.子集的异或和的算术和.2.子集的异或和的异或和.3.子集的算术和的算术和.4.子集的算术和的异或和.目前为止,小呆已经解决了前三个问题 ...

  9. 【bzoj4247】挂饰 背包dp

    题目描述 JOI君有N个装在手机上的挂饰,编号为1...N. JOI君可以将其中的一些装在手机上. JOI君的挂饰有一些与众不同——其中的一些挂饰附有可以挂其他挂件的挂钩.每个挂件要么直接挂在手机上, ...

随机推荐

  1. Bootstrap form-group and form-control

    https://github.com/twbs/bootstrap/blob/21f3375f21e9a7a5155d0cd783fd2bc7aeee8485/scss/_forms.scss htt ...

  2. nginx - nginx下配置thinkphp5

    首先tp5的访问目录指向到webroot/public文件夹中.thinkphp的url访问:http://serverName/index.php(或者其它应用入口文件)/模块/控制器/操作/[参数 ...

  3. MongoDB(mongodb-win32-x86_64-enterprise-windows-64-4.2.1-signed.msi)下载,启动和插入数据,查询

    下载链接:https://pan.baidu.com/s/19lM5Q-_BaDbjaO1Pj0SbYg&shfl=sharepset 安装一路Next就行,安装完毕后,进入目录C:\Prog ...

  4. git如何将一个远程仓库的某个分支拉取到当前分支?

    答: git pull <remote_repository_url> <branch_name> 例如: git clone https://github.com/lede- ...

  5. SQL-W3School-基础:SQL DELETE 语句

    ylbtech-SQL-W3School-基础:SQL DELETE 语句 1.返回顶部 1. DELETE 语句 DELETE 语句用于删除表中的行. 语法 DELETE FROM 表名称 WHER ...

  6. kotlin委托属性

    fun main(arg: Array<String>) { val myClass1 = myClass1() myClass1.name="mycalsss1" v ...

  7. linux下怎么用ssh连接另一台linux服务器

    linux系统大家都知道是服务器版本一般都没有图像界面,通过字符界面操作.用ssh远程方式远程,如果要从一台linux远程到另外一台系统应该怎么操作呢本经验咗嚛以cenots7为例演示   方法/步骤 ...

  8. Flutter路由_fluro引入配置和使用

    Flutter本身提供了路由机制,作个人的小型项目,完全足够了.但是如果你要作企业级开发,可能就会把入口文件变得臃肿不堪.而再Flutter问世之初,就已经了企业级路由方案fluro. flutter ...

  9. Vscode中打开、新建内部终端快捷键方法

    设置->键盘快捷方式->搜索集成终端->切换集成终端/新建集成终端 Windows 电脑 组合键 说明 Ctrl + ~ 打开默认终端 Ctrl + Shift + ~ 新建新的终端 ...

  10. webdriervAPI(定位一组元素)

    通过定位一组元素的方法来,来勾选自己需要勾选的选项. from selenium import webdriver from selenium.common.exceptions import NoS ...