题目链接:

垃圾陷阱

题目分析:

\(dp\),思路和题解大部分有点区别,建议按洛谷题解写,这个有点丑
看成\(0/1\)背包之后发现是菜题
先假设牛把有命吃到的垃圾全都食下去了,然后记成生命值按时间消耗
\(dp[i][j]\)表示处理到第\(i\)个垃圾,生命值还剩\(j\)时的最高高度
具体方程看代码,懒得打\(LaTeX\)

代码:

#include<bits/stdc++.h>
#define N (100 + 10)
using namespace std;
inline int read() {
    int cnt = 0, f = 1; char c = getchar();
    while (!isdigit(c)) {if (c == '-') f = -f; c = getchar();}
    while (isdigit(c)) {cnt = (cnt << 3) + (cnt << 1) + c - '0'; c = getchar();}
    return cnt * f;
}
const int INF = (1 << 30);
int d, g, dp[N][N * 10], ans = (1 << 30), tmp = 0;
int vis[N][N * 10];
int lim;
struct node {
    int t, f, h;
}a[N];
bool cmp(node a, node b) {
    return a.t < b.t;
}
int main() {
//    freopen("1.txt", "r", stdin);
    d = read(), g = read();
    for (register int i = 1; i <= g; ++i)
        a[i].t = read(), a[i].f = read(), a[i].h = read();
    sort(a + 1, a + g + 1, cmp);
    lim = 10;
    vis[0][10] = 1;
    for (register int i = 1; i <= g; ++i) {
        if (a[i].t > lim) break;
        lim += a[i].f;
    }
    for (register int i = 1; i <= g; ++i) {
        tmp += a[i].t - a[i - 1].t;
        for (register int j = lim; j >= 0; --j) {
            int delta = a[i].t - a[i - 1].t;
            if (vis[i - 1][j + delta]) dp[i][j] = max(dp[i][j], dp[i - 1][j + delta] + a[i].h), vis[i][j] = 1;
            if (vis[i - 1][j + delta]) dp[i][j + a[i].f] = max(dp[i][j + a[i].f], dp[i - 1][j + delta]), vis[i][j + a[i].f] = 1;

            if (dp[i][j] >= d) {ans = a[i].t; break;}
        }
        if (ans != INF) break;
    }
    if (ans != INF) printf("%d", ans);
    else printf("%d", lim);
    return 0;
} 
02-12 04:30