【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;
}
隐约雷鸣,阴霾天空,但盼风雨来,能留你在此。
隐约雷鸣,阴霾天空,即使天无雨,我亦留此地。