• BZOJ 2794 [Poi2012]Cloakroom(离线+背包)


    2794: [Poi2012]Cloakroom

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 406  Solved: 241
    [Submit][Status][Discuss]

    Description

    有n件物品,每件物品有三个属性a[i], b[i], c[i] (a[i]<b[i])。
    再给出q个询问,每个询问由非负整数m, k, s组成,问是否能够选出某些物品使得:
    1. 对于每个选的物品i,满足a[i]<=m且b[i]>m+s。
    2. 所有选出物品的c[i]的和正好是k。

    Input

    第一行一个正整数n (n<=1,000),接下来n行每行三个正整数,分别表示c[i], a[i], b[i] (c[i]<=1,000, 1<=a[i]<b[i]<=10^9)。
    下面一行一个正整数q (q<=1,000,000),接下来q行每行三个非负整数m, k, s (1<=m<=10^9, 1<=k<=100,000, 0<=s<=10^9)。

    Output


    输出q行,每行为TAK (yes)或NIE (no),第i行对应第i此询问的答案。

    Sample Input

    5

    6 2 7

    5 4 9

    1 2 4

    2 5 8

    1 3 9

    5

    2 7 1

    2 7 2

    3 2 0

    5 7 2

    4 1 5

    Sample Output

    TAK

    NIE

    TAK

    TAK

    NIE

    HINT

    题解

    这题还行。

    看了一会,自信满满,然后就死了。

    离线把询问按s排序。把每一个物品按a[i]排序。

    然后dp[i]代表当c的和能凑成i时所用的物品b的最小值的最大值。

    因为排序后每一个物品只需计算一次,所以复杂度没有飞。(但至少我看来有问题)

    所以对于每一个询问,只需判断dp[k]是否大于m+s就行了。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 struct thing{
     8     int c,a,b;
     9 }g[2000];
    10 struct query{
    11     int l,r,k,id;
    12 }q[1000100];
    13 int n,t,dp[100100],ans[1000100],mx;
    14 bool cmp(thing a,thing b){
    15     return a.a<b.a;
    16 }
    17 bool mmp(query a,query b){
    18     return a.l<b.l;
    19 }
    20 int main(){
    21     scanf("%d",&n);
    22     for(int i=1;i<=n;i++){
    23         scanf("%d%d%d",&g[i].c,&g[i].a,&g[i].b);
    24     }
    25     scanf("%d",&t);
    26     for(int i=1;i<=t;i++){
    27         int s,k,m;
    28         scanf("%d%d%d",&s,&k,&m);
    29         q[i].l=s;
    30         q[i].r=s+m;
    31         q[i].k=k;
    32         q[i].id=i;
    33         mx=max(mx,k);
    34     }
    35     sort(g+1,g+1+n,cmp);
    36     sort(q+1,q+1+t,mmp);
    37     dp[0]=1999999999;
    38     for(int i=1,now=1;i<=t;i++){
    39         while(now<=n&&g[now].a<=q[i].l){
    40             for(int j=mx;j>=g[now].c;j--){
    41                 dp[j]=max(dp[j],min(dp[j-g[now].c],g[now].b));
    42             }
    43             now++;
    44         }
    45         ans[q[i].id]=(q[i].r<dp[q[i].k]);
    46     }
    47     for(int i=1;i<=t;i++){
    48         if(ans[i])printf("TAK
    ");
    49         else printf("NIE
    ");
    50     }
    51     return 0;
    52 } 
  • 相关阅读:
    HDU6168 Numbers
    HDU6170 Two strings
    UVA11426 GCD
    hihocoder1560 H国的身份证号码II
    HDU6156 Palindrome Function
    UVA10917 Walk Through the Forest
    UVA11374 Airport Express
    hihocoder1323 回文字符串
    hihocoder1543 SCI表示法
    CodeForces501C Misha and Forest
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9588448.html
Copyright © 2020-2023  润新知