您的位置:首页 > 其它

bzoj 2794 [Poi2012]Cloakroom dp

2016-11-15 09:45 253 查看
一开始写了个线段树,每个节点维护个背包,然后发现查询时没法合并,就gg了。

先把所有点按m和a[i]排序。然后就是支持添加物品,询问能组成k的b[i]的最小值最大。然后直接dp就好了。

#include <bits/stdc++.h>
using namespace std;
#define N 1100
#define M 1100000
#define A 100000
#define ls l,mid,now<<1
#define rs mid+1,r,now<<1|1
int n,q,top;
int ans[M],f[A+10];
struct node
{
int x,y,z,pos;
node(){}
node(int x,int y,int z):x(x),y(y),z(z){}
friend bool operator < (const node &r1,const node &r2)
{return r1.x<r2.x;}
}a
,b[M];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d%d",&a[i].z,&a[i].x,&a[i].y);
sort(a+1,a+1+n);
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
scanf("%d%d%d",&b[i].x,&b[i].y,&b[i].z);
b[i].pos=i;b[i].z+=b[i].x;
}
sort(b+1,b+1+q);f[0]=1<<30;
for(int i=1,now=1;i<=q;i++)
{
while(now<=n&&a[now].x<=b[i].x)
{
for(int j=A;j>=a[now].z;j--)
f[j]=max(f[j],min(f[j-a[now].z],a[now].y));
now++;
}
ans[b[i].pos]=f[b[i].y]>b[i].z ? 1:0;
}
for(int i=1;i<=q;i++)
puts(ans[i] ? "TAK":"NIE");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: