题解 P1156 【垃圾陷阱】
这道题可以把它想成一个背包问题,一个dp就ok了
(被这道题卡了一天的窝瑟瑟发抖,重点是最后还是找了神犇帮我看题)
嘤嘤嘤
这里井的高度就好比背包中的剩余空间,垃圾好比物重,剩余体力好比物品价值。
所以,这里dp[i][j]就代表第i个垃圾,高度为j时所剩余最大体力值。
然后就可以简单的(我花了1h)列出dp方程
dp[i][j+a[i].h] = max(dp[i][j+a[i].h],dp[i-1][j]-(a[i].t-a[i-1].t));//吃辣鸡
dp[i][j] = max(dp[i][j],dp[i-1][j]+a[i].v-(a[i].t-a[i-1].t));//不吃辣鸡
(这里a结构体表示每一个辣鸡的t丢出时间,v价值,h高度)
下面附上AC代码(我没用滚动数组,52ms貌似不慢)
/*The Bone Of My Sword*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#define MAXN 1005
using namespace std;
int dp[MAXN][MAXN];
int n,d;
struct r{
int t,v,h;
}a[MAXN];
bool cmp(struct r q,struct r p){
return q.t<p.t;
}
int ans;
int main(void){
cin >> d >> n;
for(int i = 1;i <= n;i ++){
cin >> a[i].t >> a[i].v >> a[i].h;
} memset(dp,~0x3f3f3f,sizeof(dp));
sort(a+1,a+1+n,cmp);
dp[0][0] = 10;
a[0].t = 0;
ans = -999999;
for(int i = 1;i <= n;++ i){
memset(dp[i],~0x3f3f3f,sizeof(dp[i]));
for(int j = d;j >= 0;-- j){
if(dp[i-1][j]<a[i].t-a[i-1].t)continue;
if(j+a[i].h>=d){
cout << a[i].t <<endl;
return 0;
}
dp[i][j+a[i].h] = max(dp[i][j+a[i].h],dp[i-1][j]-(a[i].t-a[i-1].t));
dp[i][j] = max(dp[i][j],dp[i-1][j]+a[i].v-(a[i].t-a[i-1].t));
}
ans=max(ans,dp[i][0]+a[i].t);
}
cout << ans << endl;
return 0;
}