【luogu P1156 垃圾陷阱】 题解

题目链接:https://www.luogu.org/problemnew/show/P1156

\(dp[i][j]\)表示前i堆到达高度j时的所活最长时间
那么一旦到当前状态能到达满足的时间和高度就输出这个垃圾来的时间
转移时先满足可以到达的时间,
再有转移高度:\(dp[i+1][j+a[i+1].h] = dp[i][j] - (a[i+1].t - a[i].t)\)
转移生命值:\(dp[i+1][j] = max(dp[i][j]+a[i+1].f-(a[i+1].t-a[i].t), dp[i+1][j])\)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1010;
int dp[1010][1010], n, m, d;
struct trash{
	int t, h, f;
}a[maxn];
bool cmp(trash a, trash b)
{ 
	if(a.t == b.t) return a.h > b.h;
	return a.t < b.t;
}
int main()
{
	//freopen("testdata.in","r",stdin);
	ios::sync_with_stdio(false);
	//dp[i][j]表示 前i堆能到j高度所活的最长时间 
	cin>>d>>n;
	for(int i = 1; i <= n; i++) cin>>a[i].t>>a[i].f>>a[i].h;
	sort(a+1, a+1+n, cmp);
	memset(dp, -1, sizeof(dp));
	dp[0][0] = 10;
	a[0].t = 0, a[0].f = 0, a[0].h = 0;
	for(int i = 0; i < n; i++)
		for(int j = 0; j <= d; j++)
		{
			if(dp[i][j] < 0) continue;
			if(dp[i][j] >= a[i+1].t-a[i].t && j + a[i+1].h >= d) {cout<<a[i+1].t; return 0;}
			if(dp[i][j] >= a[i+1].t-a[i].t) dp[i+1][j+a[i+1].h] = dp[i][j]-a[i+1].t+a[i].t;
			if(dp[i][j] >= a[i+1].t-a[i].t) dp[i+1][j] = max(dp[i][j]+a[i+1].f-(a[i+1].t-a[i].t), dp[i+1][j]);
		}
	int now = 10;
	for(int i = 1; i <= n; i++)
	{
		if(a[i].t - a[i-1].t > now) {printf("%d",now+a[i-1].t); return 0;}
		if(a[i].t - a[i-1].t <= now) {now += a[i].f; now = now - (a[i].t - a[i-1].t);}
	}
	cout<<a[n].t+now;
	return 0;
}

posted @ 2018-10-18 09:36  Misaka_Azusa  阅读(129)  评论(0编辑  收藏  举报
Live2D