P3537 [POI2012] SZA-Cloakroom 题解

对一次询问 $m,k,s$,求出在 $a_i\le m$ 的物品中选出一些物品满足 $\sum c_i=k$ 时 $\min b_i$ 最大值 $f$,若 $f>m+s$ 则答案为 TAK,否则为 NIE

把物品按 $a$ 从小到大排序,询问按 $m$ 从小到大排序,这样 $a_i\le m$ 的物品集是只加不减的。

设 $f_k$ 表示在目前考虑的物品中选出一些物品满足 $\sum c_i=k$ 时 $\min b_i$ 最大值,

考虑加入物品 $i$ 的贡献,有转移 $f_{k}\gets\max\{f_k,\min\{f_{k-c_i},b_i\}\}$。

则处理一次询问 $m,k,s$ 时,先加入所有 $a_i\le m$ 的物品,然后若 $f_k>m+s$ 则答案为 TAK,否则为 NIE

#include <cstdio>
#include <algorithm>
using namespace std;
struct S
{
    int a, b, c;
} a[1050];
struct Q
{
    int m, k, s, i;
} q[1000050];
int n, m, f[100050];
bool b[1000050];
bool C1(S x, S y) { return x.a < y.a; }
bool C2(Q x, Q y) { return x.m < y.m; }
int main()
{
    scanf("%d", &n);
    for (int i = 0; i < n; ++i)
        scanf("%d%d%d", &a[i].c, &a[i].a, &a[i].b);
    sort(a, a + n, C1);
    scanf("%d", &m);
    for (int i = 0; i < m; ++i)
        scanf("%d%d%d", &q[i].m, &q[i].k, &q[i].s), q[i].i = i;
    sort(q, q + m, C2);
    f[0] = 1e9;
    for (int i = 0, j = 0; i < m; ++i)
    {
        for (; j < n && a[j].a <= q[i].m; ++j)
            for (int l = 1e5; l >= a[j].c; --l)
                f[l] = max(f[l], min(f[l - a[j].c], a[j].b));
        b[q[i].i] = f[q[i].k] > q[i].m + q[i].s;
    }
    for (int i = 0; i < m; ++i)
        puts(b[i] ? "TAK" : "NIE");
    return 0;
}
posted @ 2023-07-04 09:54  Jijidawang  阅读(14)  评论(0)    收藏  举报  来源