bzoj2794:[Poi2012]Cloakroom

传送门

背包,想到一个思路这个题就没了,还是很简单的
将物品按\(a_i\)从小到大排序,询问按\(m\)从小到大排序,限制一下\(a_i\),最大化\(b_i\)的最小值就没了
代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
void read(int &x) {
    char ch; bool ok;
    for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
    for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
}
#define rg register
const int maxn=1010;
int n,f[100010],m,ans[1000010];
struct oo{int a,b,c;}a[maxn];
struct o{int a,b,c,id;}b[1000010];
bool cmp(oo a,oo b){return a.a<b.a;}
bool Cmp(o a,o b){return a.a<b.a;}
int main()
{
    read(n);
    for(rg int i=1;i<=n;i++)read(a[i].c),read(a[i].a),read(a[i].b);
    read(m);
    for(rg int i=1;i<=m;i++)read(b[i].a),read(b[i].b),read(b[i].c),b[i].id=i;
    sort(a+1,a+n+1,cmp),sort(b+1,b+m+1,Cmp);
    int now=1;f[0]=1e9;
    for(rg int i=1;i<=m;i++)
    {
        while(now<=n&&a[now].a<=b[i].a)
        {
            for(rg int j=100000;j>=a[now].c;j--)
                if(f[j-a[now].c])
                {
                    if(!f[j])f[j]=min(f[j-a[now].c],a[now].b);
                    else f[j]=max(f[j],min(f[j-a[now].c],a[now].b));
                }
            now++;
        }
        if(f[b[i].b]&&f[b[i].b]>b[i].c+b[i].a)ans[b[i].id]=1; 
    }
    for(rg int i=1;i<=m;i++)puts(ans[i]?"TAK":"NIE");
}

猜你喜欢

转载自www.cnblogs.com/lcxer/p/10491011.html