[題解]luogu P1156 垃圾陷阱
前言:[數據刪除]
來源:題解
不發題面了
首先我们来分析题目,“每个垃圾都可以用来吃或堆放”,浓浓的透露出一个背包气息。我们可以类比背包问题的放或不放。于是dp[i][j]dp[i][j]dp[i][j]描述为处理前i个物品的某状态j,那么状态j代表什么呢?
我们可以继续分析题目并使用排除法分析题目,我们需要求的答案是时间,于是很自然而然的想到j描述高度或生命,而dp数组存放时间。很显然,这样状态既不完整,也写不出转移方程。而且dp数组存的是当前状态下最大或最小的价值,似乎也不满足。
这时候我们发现,有4个值可能成为状态,高度,生命,物品和时间,难道要dp三维的吗?
再分析题目,每个垃圾都有一个下落的时间,奶牛一定是在垃圾丢下来的时间就处理垃圾的(可以得出这样的最优的),那么物品就可以和时间关联起来了。这时候,我们可以把时间仅仅当作干扰量给剔除了。
需要注意的是,物品的使用顺序并不是随意的,必须按它们下落的时间顺序来先后处理。(这里排一下序即可)
那么j代表什么呢?
一下子我们并不能得出答案。先尝试dp[i][j]代表前i件物品处理后在j血量时达到的最大高度。
值得一提的是,j血量表示奶牛在暂时不考虑时间时所得到的最大血量
据说这个是叫离线
试着写一下它的状态转移方程
dp[i][j]=max(dp[i−1][j]+trash[i].h,dp[i−1][j+trash[i].c])
发现这是对的,然而我们再想想,在关于j的一重循环里面,对j的取值我们似乎并不好判断,甚至要枚举很大。
所以我们再尝试讨论dp[i][j]代表前i件物品处理后在h高度时达到的最大血量。
状态转移
dp[i][j]=max(dp[i−1][j]+trash[i].c,dp[i−1][j−trash[i].h])
发现这样也是对的,而且j枚举起来也比较方便,于是我们选择这种算法。
重要内容:分析 i,j 代表什么:
按時間順序排序然後依次轉移,時間數值不固定或者比較大不太好做階段,而且會有很多浪費,所以用前 i 個物品轉移,轉移時在判可行性,處理掉了時間,
只剩 血量,高度兩維,在考慮怎麼分配,如果用血量做第二維的話數值仍然不確定而且可能很大,於是嘗試交換,對於能否活下來在最後找解的時候在判斷。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int d,g;
struct node{
int t,h,f;
}e[];
int f[][];//i個物品j高度的最大血量(重要
bool cmp(node a,node b)
{
return a.t<b.t;
}
int main()
{
scanf("%d%d",&d,&g);
for(int i=;i<=g;i++){
scanf("%d%d%d",&e[i].t,&e[i].f,&e[i].h);
}
sort(e+,e++g,cmp);
f[][]=;//初值
for(int i=;i<=g;i++)
for(int j=;j<=d;j++){
if(f[i-][j]>=e[i].t)//如果上一個狀態的血量夠用
f[i][j]=max(f[i][j],f[i-][j]+e[i].f);//吃
if(j>=e[i].h&&f[i-][j-e[i].h]>=e[i].t)//如果可以從前一個更低的高度加上這個物品的高度,並且能堅持到下一個垃圾
f[i][j]=max(f[i][j],f[i-][j-e[i].h]);//填
}
int maxh=,maxt=,i;
for(i=;i<=g;i++){
for(int j=;j<=d;j++){
if(f[i][j]-e[i].t>=)//一定要判狀態能否使用
maxh=max(maxh,j);//更新最高高度
maxt=max(maxt,f[i][j]);//每次都要更新最長時間
}
if(maxh>=d)break;
}
if(maxh>=d)printf("%d",e[i].t);
else printf("%d",maxt);
}
[題解]luogu P1156 垃圾陷阱的更多相关文章
- 【luogu P1156 垃圾陷阱】 题解
题目链接:https://www.luogu.org/problemnew/show/P1156 设\(dp[i][j]\)表示前i堆到达高度j时的所活最长时间 那么一旦到当前状态能到达满足的时间和高 ...
- Luogu P1156 垃圾陷阱 DP
f[i][j]表示在第i个垃圾,高度为j的最大生命值 转移分三部分: 如果j>=当前垃圾的高度,且两个垃圾间的时间小于等于上一个状态f[i-1][j-a[i].v]的生命值,则可以垫高度 如果j ...
- [Luogu] P1156 垃圾陷阱
题目描述 卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中.“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2≤D≤100)英尺. 卡门想把垃圾堆起来,等到堆得与井同样高时 ...
- Luogu P1156 垃圾陷阱 【dp】By cellur925
题目传送门 这题...看上去浓浓的背包气息...但是并不好设计状态啊emmm. 我们考虑可能成为状态的量:高度.血量.时间.物品.看数据范围也猜到应该大概是个二维dp了w. 正确的状态设计之一:设$f ...
- 洛谷 P1156 垃圾陷阱
2016-05-31 09:54:03 题目链接 :洛谷 P1156 垃圾陷阱 题目大意: 奶牛掉坑里了,给定坑的深度和方块的个数,每个方块都可以垫脚或者吃掉维持生命(初始为10) 若可以出来,求奶牛 ...
- 【洛谷】P1156 垃圾陷阱【DP】
P1156 垃圾陷阱 题目描述 卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中.“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2≤D≤100)英尺. 卡门想把垃圾堆起来 ...
- 【题解】P1156垃圾陷阱
[题解]P1156 垃圾陷阱 乍看此题,我们感觉状态很多,很复杂. 遇到这类型条件比较多的\(dp\),我们不要首先考虑全部设出来,而是要看到这些状态的本质.而在这道题目中,时间和高度就是关键. 考虑 ...
- 洛谷——P1156 垃圾陷阱
P1156 垃圾陷阱 题目描述 卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中.“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2 \le D \le 100)D(2≤D ...
- [題解] luogu p1220 關路燈
區間dp 题目描述 某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少).老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯. ...
随机推荐
- CSS控制文本的长度,超过一行显示省略号
代码如下: <div style="width:100px;height:20px;text-overflow:ellipsis; white-space:nowrap; overfl ...
- 将PHP数组输出为HTML表格
1. [代码][PHP]代码 <?phpclass xtable{ private $tit,$arr,$fons,$sextra; public function __con ...
- 通用方法解决UITextFiled输入的时候,键盘遮挡问题
我们在用键盘录入的时候,有可能会遮挡录入框,所以我们应调整UIView的位置,使其不被遮挡.我写了一个通用的方法可以解决这个问题:1. [代码][C/C++]代码 - (void) ...
- codeforces C. New Year Ratings Change 解题报告
题目链接:http://codeforces.com/problemset/problem/379/C 题目意思:有n个users,每个user都有自己想升的rating.要解决的问题是给予每个人不同 ...
- reactjs的一些笔记
1.使用虚拟DOM作为其不同的实现.同时可以由服务器node.js渲染,从而不需要过重的浏览器DOM支持. 2.虚拟DOM:在浏览器端用javascript实现了一套DOM API.用react开 ...
- PIL 安装及使用
我ubunto虚拟机自带的是python2.7,好像PIL也只支持到2.7. PIL包的安装 Debian/Ubunto Linux下直接安装: sudo apt-get install python ...
- 关于内存DC
使用CreateCompatibleDC 创建了内存DC之后,要再调用SelectObject选择一张位图放入此DC,然后才可以使用此DC进行绘制,之后绘制的数据会保存在内存中, 详细说明看后文. 在 ...
- HDU1525 Euclid's Game
Two players, Stan and Ollie, play, starting with two natural numbers. Stan, the first player, subtra ...
- Mysql数据库的打开和关闭
Mysql数据库的打开和关闭: 选择计算机(win7)-右键管理 在新窗口选择--服务 5 找到mysql,然后右键-启动(停止)
- java并发之阻塞队列LinkedBlockingQueue与ArrayBlockingQueue
Java中阻塞队列接口BlockingQueue继承自Queue接口,并提供put.take阻塞方法.两个主要的阻塞类实现是ArrayBlockingQueue和LinkedBlockingQueue ...