……

解题报告:luogu P1156

题目链接:P1156 垃圾陷阱
大佬推荐的一个题,就尝试做了做,然后就自闭了,相信大佬做的时候直接秒的吧。
首先确定选择顺序,即按放入的时间排序。
容易想到用一维代表选到了第几个垃圾。
考虑分填与吃两种情况,分别更新。
我们容易想到设\(dp[i][j]\)为前\(i\)个垃圾,堆\(j\)高度剩下的做多时间。
那么显然可以这样:

\[dp[i][j]=max(dp[i][j],dp[i-1][j]-t_i+t_{i-1}+f_i) \]

\[dp[i][j]=max(dp[i][j],dp[i-1][j-h_i]-t_i+t_{i-1}) \]

当然是保证在合法的情况下。
时间复杂度是\(\mathcal O(DG)\),可以通过本题。

\(Code\):

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

#define read(x) scanf("%d",&x)

int n,H;
struct node{int t,f,h;}a[105];
int dp[205][205]={0};

bool cmp(node x,node y){return x.t<y.t;}

int main()
{
	read(H),read(n);
	for(int i=1;i<=n;i++) read(a[i].t),read(a[i].f),read(a[i].h);
	sort(a+1,a+n+1,cmp);
	for(int i=0;i<=n;i++)
	{
		for(int j=0;j<=H;j++) dp[i][j]=-100;
	}
	dp[0][0]=10;
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<=H;j++)
		{
			if(dp[i-1][j]>=a[i].t-a[i-1].t) dp[i][j]=max(dp[i][j],dp[i-1][j]-a[i].t+a[i-1].t+a[i].f);
			if(j>=a[i].h&&dp[i-1][j-a[i].h]>=a[i].t-a[i-1].t) dp[i][j]=max(dp[i][j],dp[i-1][j-a[i].h]-a[i].t+a[i-1].t);
			if(j==H&&dp[i][j]>=0){printf("%d\n",a[i].t);return 0;}
		}
	}
        //无法到达,就贪心的吃
	int sum=10;
	for(int i=1;i<=n;i++)
	{
		if(sum>=a[i].t) sum+=a[i].f;
		else{printf("%d\n",sum);return 0;}
	}
	printf("%d\n",sum);
	return 0;
}
posted @ 2020-04-13 20:03  童话镇里的星河  阅读(124)  评论(0编辑  收藏  举报