--- 这里是 cjiaw 的小窝(●'◡'●) ---

正在玩命加载中......

洛谷__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;
}

 

posted @ 2025-10-26 16:45  wwjjw  阅读(15)  评论(0)    收藏  举报