# [Poi 2012] bzoj2794 Cloakroom [dp]

Description:
$n$$n$件物品，每件物品有三个属性$a\left[i\right],b\left[i\right],c\left[i\right]\left(a\left[i\right]$a[i], b[i], c[i] (a[i]

$1$$1$. 对于每个选的物品$i$$i$，满足$a\left[i\right]<=m$$a[i]<=m$$b\left[i\right]>m+s$$b[i]>m+s$
$2$$2$. 所有选出物品的$c\left[i\right]$$c[i]$的和正好是$k$$k$

Solution:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1e6 + 5;
struct data_1 {
int a, b, c;
bool friend operator < (const data_1 &a, const data_1 &b) {
return a.a < b.a;
}
} a[maxn];
struct data_2 {
int m, s, k, id;
bool friend operator < (const data_2 &a, const data_2 &b) {
return a.m < b.m;
}
} b[maxn];
int n, m;
int dp[maxn], ans[maxn];
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
scanf("%d%d%d", &a[i].c, &a[i].a, &a[i].b);
}
sort(a + 1, a + n + 1);
scanf("%d", &m);
for(int i = 1; i <= m; ++i) {
scanf("%d%d%d", &b[i].m, &b[i].k, &b[i].s);
b[i].id = i;
}
sort(b + 1, b + m + 1);
dp[0] = 1e9;
for(int i = 1, j = 0; i <= m; ++i) {
while(j < n && b[i].m >= a[j + 1].a) {
++j;
for(int k = 100000; k >= a[j].c; --k) {
dp[k] = max(dp[k], min(dp[k - a[j].c], a[j].b));
}
}
if(dp[b[i].k] > b[i].m + b[i].s) {
ans[b[i].id] = 1;
}
}
for(int i = 1; i <= m; ++i) {
puts(ans[i] ? "TAK" : "NIE");
}
return 0;
}

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120