洛谷__P1156 垃圾陷阱(背包DP)
题目链接:P1156 垃圾陷阱 - 洛谷
题目大意:
卡门掉进深度为 D 英尺的井里。她可以通过堆放垃圾来增加高度,或者吃掉垃圾来延长存活时间。
每个垃圾有投放时间 t、堆放高度 h 和增加的生命时间 f。
求出她最早能逃出井的时间,若不能逃出,则输出最长存活时间。
思路:
注意到,每当垃圾掉下来时,只有两个选择,堆放 或 吃掉,
如果是堆放,那么高度会增加 h,生命值不变 ,
如果是吃掉,那么高度不变,生命值会增加 f ;
枚举 D~0 高度,如果当前高度下的生命值大于物品掉落时间,可以选择堆放 或 吃掉,
维护数组 dp[i] ,表示在 i 高度下的生命值
如果堆放,dp[i+h]=max( dp[i+h] , dp[i] + h ) ,
如果吃掉,dp[i] = dp[i] + f ;
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<bitset>
#include<tuple>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define mst(a,x) memset(a,x,sizeof (a))
using namespace std;
typedef pair<int, int> pii;
const int N = 408, mod = 998244353;
int d, n;
int dp[N];//高度为N时的 HP
struct node {
int t, f, h;
} e[N];
bool cmp(node a, node b) {
return a.t < b.t;
}
void solve() {
cin >> d >> n;
for (int i = 1; i <= n; i++) {
int t, f, h;
cin >> t >> f >> h;
e[i] = {t, f, h};
}
sort(e + 1, e + n + 1, cmp);//排序
mst(dp, -1);
dp[0] = 10;//开始0高度时的生命值为10
for (int i = 1; i <= n; i++) {
for (int j = d; j >= 0; j--) {
auto[t, f, h] = e[i];
if (t > dp[j]) continue;//掉落物品的时间大于 高度j 的生命值就饿死了
if (h + j >= d) {
cout << t << endl;//能出去就输出当前掉下的食物的时间
return;
}
dp[h + j] = max(dp[h + j], dp[j]);//不吃食物,在高度j 取生命的最大值
dp[j] += f;//高度j 吃掉食物
}
}
cout << dp[0] << endl;//一直吃不往上爬活得最久
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}

浙公网安备 33010602011771号