• dp(背包)


                                                                                                                Cloakroom

    题目描述

    • 有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

    输入格式

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

    输出格式

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

    样例输入

    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
    

    样例输出

    TAK
    NIE
    TAK
    TAK
    NIE
    
    思路:首先:若只有第二种限制,则是一个裸的背包,所以,我们可以在01背包的基础上限制第一个条件
    第二:限制a[i]<=m,将a[i]升序排列,将m也升序排列(所以需要离线操作,注意记录每个询问对应的序号,以便输出)
       第三:限制b[i]>m+s,将f[i]定义为装满容量为i的背包所有方案中每个方案最小b[i]的最大值(每个方案选最小b[i],确保方案中所有的b[i]都满足b[i]>m+s,因为一种方案中最小的b[i]都比m+s大,其他肯定也比m+s大
    选最大值是因为每个容量只需一种方案满足即可,所以应选所有方案中最小b[i]的最大值更容易符合要求)
     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 const int maxn=1000+10,inf=0x3f3f3f3f;
     5 int n,mm;
     6 int f[1000000+10];
     7 struct Node{
     8     int a,b,c;
     9     bool operator <(const Node &A)const{
    10         return a<A.a;
    11     }
    12 }e[maxn];
    13 struct Node1{
    14     int m,k,s,id;
    15     bool operator <(const Node1 &a)const{
    16         return m<a.m;
    17     }
    18 }q[1000000+10];
    19 int ans[1000000+10];
    20 void solve(){
    21     int j=1;
    22     f[0]=inf;
    23     for(int i=1;i<=mm;i++){
    24         int m=q[i].m,k=q[i].k,s=q[i].s;
    25         while(j<=n&&e[j].a<=m){//限制a[i]<=m,若e[j]不符合要求,跳出循环,当循环到下一个i时以前确定的f[i]值不变
    26             for(int w=100000;w>=e[j].c;w--){
    27                 f[w]=max(f[w],min(f[w-e[j].c],e[j].b));
    28             }//01背包
    29             j++;
    30         }
    31         if(f[k]>m+s) ans[q[i].id]=1;//若符合,则为真,注意ans的下标为查询的序号而不是排序之后的
    32     }
    33     for(int i=1;i<=mm;i++){
    34         if(ans[i]) printf("TAK
    ");
    35         else printf("NIE
    ");
    36     }
    37 }
    38 int main(){
    39     scanf("%d",&n);
    40     for(int i=1;i<=n;i++){
    41         scanf("%d%d%d",&e[i].c,&e[i].a,&e[i].b);
    42     }
    43     sort(e+1,e+1+n);//对a排升序
    44     scanf("%d",&mm);
    45     for(int i=1;i<=mm;i++){
    46         scanf("%d%d%d",&q[i].m,&q[i].k,&q[i].s);
    47         q[i].id=i;
    48     }
    49     sort(q+1,q+1+mm);//对m排升序
    50     solve();
    51     return 0;
    52 }
    View Code
     
  • 相关阅读:
    pg 基础操作
    mybatis+pg常见错误
    mybatis 需要注意事项
    java编程中的Dao,service,controller,View
    java 中的spring基础
    werkzeug(flask)中的local,localstack,localproxy探究
    gevent
    cookie和session
    关于redis数据库的简单思考
    对阻塞,非阻塞,同步,异步的深入理解
  • 原文地址:https://www.cnblogs.com/HZOIDJ123/p/13340004.html
Copyright © 2020-2023  润新知