luogu1156垃圾陷阱题解--背包DP
题目链接
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的更多相关文章
- [luogu1156]垃圾陷阱_动态规划_背包dp
垃圾陷阱 luogu-1156 题目大意:Holsteins在距离地面D英尺的地方,FJ间隔时间ti会往下扔第i个垃圾.Holsteins对待每一个垃圾都会选择吃掉或者垫高.Holsteins有10个 ...
- 垃圾陷阱洛谷dp
题目描述 卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中.“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2<=D<=100)英尺. 卡门想把垃圾堆起来,等到 ...
- 洛谷P1156 垃圾陷阱【线性dp】
题目:https://www.luogu.org/problemnew/show/P1156 题意: 每一个垃圾投放时间是t,可以堆的高度是h,如果吃掉可以增加的生命值是f. 给定g个垃圾,初始生命值 ...
- 洛谷 P1156 垃圾陷阱 题解
题目传送门 dp+排序+01背包 就完事了??? 貌似就是这样的 代码: //dp 排序 01背包 #include<iostream> #include<cstdio> #i ...
- [bzoj2287]消失之物 题解(背包dp)
2287: [POJ Challenge]消失之物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1138 Solved: 654[Submit][ ...
- 【bzoj5018】[Snoi2017]英雄联盟 背包dp
题目描述 正在上大学的小皮球热爱英雄联盟这款游戏,而且打的很菜,被网友们戏称为「小学生」.现在,小皮球终于受不了网友们的嘲讽,决定变强了,他变强的方法就是:买皮肤!小皮球只会玩N个英雄,因此,他也只准 ...
- 【bzoj1222】[HNOI2001]产品加工 背包dp
题目描述 某加工厂有A.B两台机器,来加工的产品可以由其中任何一台机器完成,或者两台机器共同完成.由于受到机器性能和产品特性的限制,不同的机器加工同一产品所需的时间会不同,若同时由两台机器共同进行加工 ...
- 【bzoj3687】简单题 背包dp+STL-bitset
题目描述 小呆开始研究集合论了,他提出了关于一个数集四个问题:1.子集的异或和的算术和.2.子集的异或和的异或和.3.子集的算术和的算术和.4.子集的算术和的异或和.目前为止,小呆已经解决了前三个问题 ...
- 【bzoj4247】挂饰 背包dp
题目描述 JOI君有N个装在手机上的挂饰,编号为1...N. JOI君可以将其中的一些装在手机上. JOI君的挂饰有一些与众不同——其中的一些挂饰附有可以挂其他挂件的挂钩.每个挂件要么直接挂在手机上, ...
随机推荐
- kotlin之函数的基本用法
fun main(arg: Array<String>) { val )//调用函数 print(double) } fun double(x:Int):Int{ *x } kotlin函 ...
- 实时流Streaming大数据:Storm,Spark和Samza
当前有许多分布式计算系统能够实时处理大数据,这篇文章是对Apache的三个框架进行比较,试图提供一个快速的高屋建瓴地异同性总结. Apache Storm 在Storm中,你设计的实时计算图称为top ...
- Python字符串逐字符或逐词反转方法
Python字符串逐字符或逐词反转方法 这篇文章主要介绍了Python字符串逐字符或逐词反转方法,本文对逐字符或逐词分别给出两种方法,需要的朋友可以参考下 目的 把字符串逐字符或逐词反转过来,这个蛮有 ...
- Hadoop常用命令介绍
本文主要介绍 Hadoop 常用的命令. test命令 用于检测文件或目录是否存在,判断文件或目录大小. -test -[defsz] <path> : Answer various qu ...
- django项目添加路由----返回给客户端内容-----windows中的python
django项目添加路由 url函数的第一个参数是匹配url路径的正则表达式,第2个参数是路由函数 第一个正则表达式是r'^$',其中r表示正则表达式字符串不对转义符进行转义.“^”表示匹配URL路径 ...
- shell之判断文件是否存在
#!/bin/sh myPath="/var/log/httpd/" myFile="/var /log/httpd/access.log" #这里的-x 参数 ...
- socket编程之黏包
原理概述 上图是我在学习python的socket编程中遇到的黏包问题所画,以实例来说明这个高大上的黏包问题. 我们知道socket()实例中sendall()方法是无论数据有多大,一次性提交写入缓冲 ...
- Docker使用Portainer搭建可视化界面
Portainer介绍 Portainer是Docker的图形化管理工具,提供状态显示面板.应用模板快速部署.容器镜像网络数据卷的基本操作(包括上传下载镜像,创建容器等操作).事件日志显示.容器控制台 ...
- ASP.NET 拼多多用户登录授权后使用code去换取access_token
一.拼多多开放平台 由于本人刚毕业进公司实习 遇到一些问题然后想通过博客来记录和分享给大家一起学习. 第一次写博客没什么经验不是写的很好 请大家多多关照 嘴下留情哈哈 谢谢! 好了 话不多说直接进入主 ...
- [Kevin英语情报局]那些年我们说过的中式英语
一. blonde hair 金色头发 grey hair 白头发 baijiu 白酒 white wine 白葡萄酒 I don't think it's right 我认为不正确 I'm chin ...