题目描述

卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中。“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2 \le D \le 100)D(2≤D≤100)英尺。

卡门想把垃圾堆起来,等到堆得与井同样高时,她就能逃出井外了。另外,卡门可以通过吃一些垃圾来维持自己的生命。

每个垃圾都可以用来吃或堆放,并且堆放垃圾不用花费卡门的时间。

假设卡门预先知道了每个垃圾扔下的时间t(0< t \le 1000)t(0<t≤1000),以及每个垃圾堆放的高度h(1 \le h \le 25h(1≤h≤25)和吃进该垃圾能维持生命的时间f(1 \le f \le 30)f(1≤f≤30),要求出卡门最早能逃出井外的时间,假设卡门当前体内有足够持续1010小时的能量,如果卡门1010小时内没有进食,卡门就将饿死。

输入输出格式

输入格式:

第一行为22个整数,DD和 G (1 \le G \le 100)G(1≤G≤100),GG为被投入井的垃圾的数量。

第二到第G+1G+1行每行包括33个整数:T (0 < T <= 1000)T(0<T<=1000),表示垃圾被投进井中的时间;F (1 \le F \le 30)F(1≤F≤30),表示该垃圾能维持卡门生命的时间;和 H (1 \le H \le 25)H(1≤H≤25),该垃圾能垫高的高度。

输出格式:

如果卡门可以爬出陷阱,输出一个整表示最早什么时候可以爬出;否则输出卡门最长可以存活多长时间。

输入输出样例

输入样例#1: 复制

20 4
5 4 9
9 3 2
12 6 10
13 1 1
输出样例#1: 复制

13

说明

[样例说明]

卡门堆放她收到的第一个垃圾:height=9height=9;

卡门吃掉她收到的第22个垃圾,使她的生命从1010小时延伸到1313小时;

卡门堆放第33个垃圾,height=19height=19;

卡门堆放第44个垃圾,height=20height=20。

dp不出来  参考了大佬的做法!!!!!!!!!!!

一共有四种状态: 物品  时间  生命 高度    其中物品和时间是联通的(物品要按照时间顺序排好)   所有只有三个变量

可以写二维的  也可以写成一维的滚动数组

其中这两种对时间的表达方式也有所不同

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);i--)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define LL long long
#define pb push_back
#define fi first
#define REP(i,N) for(int i=0;i<(N);i++)
#define CLR(A,v) memset(A,v,sizeof A)
///////////////////////////////////
#define inf 0x3f3f3f3f
#define N 300+5
struct node
{
int life,high;
int t; }s[N];
int f[N];//前i个物品 j高度的最大血量 bool cmp(node a,node b)
{
return a.t<b.t;
} int main()
{
int d,n;
RII(d,n);
rep(i,,n)
{
RIII(s[i].t,s[i].life,s[i].high);
}
f[]=;
sort(s+,s++n,cmp);
rep(i,,n)
repp(j,d,)
if(f[j]>=s[i].t)
{
if(j+s[i].high>=d)
{
cout<<s[i].t;
return ;
}
f[j+s[i].high]=max(f[j+s[i].high],f[j]);
f[j]+=s[i].life;
}
cout<<f[];
return ; }

先尝试dp[i][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])dp[i][j]=max(dp[i−1][j]+trash[i].h,dp[i−1][j+trash[i].c])

发现这是对的,然而我们再想想,在关于j的一重循环里面,对j的取值我们似乎并不好判断,甚至要枚举很大。

所以我们再尝试讨论dp[i][j]dp[i][j]代表前i件物品处理后在h高度时达到的最大血量。

状态转移

dp[i][j]=max(dp[i-1][j]+trash[i].c,dp[i-1][j-trash[i].h])dp[i][j]=max(dp[i−1][j]+trash[i].c,dp[i−1][j−trash[i].h])

发现这样也是对的,而且j枚举起来也比较方便,于是我们选择这种算法。

总之因为高度比血量更小  所以枚举高度

#include <stdio.h>
#include <algorithm>
using namespace std;
#define maxn 1001
#define INF 0x7f7f7f7f
#define max(x,y) x>y?x:y
int f[][];
struct arr
{
int x,t,h;
}a[maxn];
int cmp(arr a,arr b)
{
return a.x<b.x;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for (int i=;i<=m;i++)
{
scanf("%d%d%d",&a[i].x,&a[i].t,&a[i].h);
}
sort(a+,a+m+,cmp);
for (int i=;i<=m;i++)
for (int j=;j<=n;j++)
f[i][j]=-INF;
f[][]=; a[].x=a[].t=a[].h=;
int fl=;
for (int i=;i<=m;i++)
{
for (int j=;j<=n;j++)
{ if (f[i-][j]-a[i].x+a[i-].x>=)
{
f[i][j]=max(f[i][j],f[i-][j]-a[i].x+a[i-].x+a[i].t);
}
if (f[i-][j-a[i].h]-a[i].x+a[i-].x>=&&j-a[i].h>=)
{
f[i][j]=max(f[i][j],f[i-][j-a[i].h]-a[i].x+a[i-].x);
if (j==n)
{
printf("%d\n",a[i].x);
fl=;
return ;
}
}
}
}
int ans=;
if (!fl)
{
for (int i=;i<=m;i++)
for (int j=;j<=n;j++)
if (f[i][j]!=INF)
ans=max(ans,f[i][j]+a[i].x);
printf("%d\n",ans);
}
}

P1156 垃圾陷阱 DP的更多相关文章

  1. 洛谷P1156 垃圾陷阱 dp

    正解:dp 解题报告: 这儿是传送门! 话说最近怎么神仙们都开始狂刷dp,,,感觉今天写了好多dp的题解的样子?(也就三四道其实× 然后这题,首先看到要么吃要么堆起来就会想到01背包趴?然后就考虑设方 ...

  2. Luogu P1156 垃圾陷阱 DP

    f[i][j]表示在第i个垃圾,高度为j的最大生命值 转移分三部分: 如果j>=当前垃圾的高度,且两个垃圾间的时间小于等于上一个状态f[i-1][j-a[i].v]的生命值,则可以垫高度 如果j ...

  3. 【洛谷】P1156 垃圾陷阱【DP】

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

  4. 洛谷 P1156 垃圾陷阱

    2016-05-31 09:54:03 题目链接 :洛谷 P1156 垃圾陷阱 题目大意: 奶牛掉坑里了,给定坑的深度和方块的个数,每个方块都可以垫脚或者吃掉维持生命(初始为10) 若可以出来,求奶牛 ...

  5. 【题解】P1156垃圾陷阱

    [题解]P1156 垃圾陷阱 乍看此题,我们感觉状态很多,很复杂. 遇到这类型条件比较多的\(dp\),我们不要首先考虑全部设出来,而是要看到这些状态的本质.而在这道题目中,时间和高度就是关键. 考虑 ...

  6. 洛谷——P1156 垃圾陷阱

    P1156 垃圾陷阱 题目描述 卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中.“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2 \le D \le 100)D(2≤D ...

  7. 洛谷P1156 垃圾陷阱[背包DP]

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

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

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

  9. Luogu P1156 垃圾陷阱 【dp】By cellur925

    题目传送门 这题...看上去浓浓的背包气息...但是并不好设计状态啊emmm. 我们考虑可能成为状态的量:高度.血量.时间.物品.看数据范围也猜到应该大概是个二维dp了w. 正确的状态设计之一:设$f ...

随机推荐

  1. jqGrid后台交互样例

    schoolManageGrid = $("#jqGrid").jqGrid({ url : ctx.path+"/api/school/querySchools&quo ...

  2. bootstrap栅格系统中同行div高度不一致的解决方法

    通过div底部的margin和padding实现,缺点:下边框无法完整显示,建议在无边框情况下使用 .row{ overflow: hidden; } [class*="col-" ...

  3. 洛谷P4117 [Ynoi2018]五彩斑斓的世界 [分块,并查集]

    洛谷 Codeforces 又是一道卡常题-- 思路 YNOI当然要分块啦. 分块之后怎么办? 零散块暴力,整块怎么办? 显然不能暴力改/查询所有的.考虑把相同值的用并查集连在一起,这样修改时就只需要 ...

  4. 用VS制作的windows服务安装包 安装完后如何让服务自动启动

    vs 服务做成安装包,如何安装以后启动服务,只要在类名为projectinstaller的类中重写commit事件即可         public override void Commit(IDic ...

  5. linux之各目录作用

    /opt目录 目录用来安装附加软件包,用户调用软件包程序放在目录/opt/package_name/bin下,package_name是安装软件包的名称 /etc目录 是用来放一些核心的配置文件 附各 ...

  6. python 之面向对象的三大特性

    面向对象的三大特性 继承 继承和组合 继承进阶 封装 封装(有待完善) 多态 多态

  7. Decimal integer conversion

    问题 : Decimal integer conversion 时间限制: 1 Sec  内存限制: 128 MB 题目描述 XiaoMing likes mathematics, and he is ...

  8. java操作office和pdf文件java读取word,excel和pdf文档内容

    在平常应用程序中,对office和pdf文档进行读取数据是比较常见的功能,尤其在很多web应用程序中.所以今天我们就简单来看一下Java对word.excel.pdf文件的读取.本篇博客只是讲解简单应 ...

  9. redis 单实例安装

    单实例安装 近些年,由于内存技术的提升.造价的下降,越来越多企业的服务器内存已增加到几百G.这样的内存容量给了内存数据库一个良好的发展环境. 而使用Redis是内存数据库的一股清流,渐有洪大之势.下面 ...

  10. 十图详解tensorflow数据读取机制(附代码)转知乎

    十图详解tensorflow数据读取机制(附代码) - 何之源的文章 - 知乎 https://zhuanlan.zhihu.com/p/27238630