zoukankan      html  css  js  c++  java
  • P3537 [POI2012]SZA-Cloakroom

    链接:https://www.luogu.org/problemnew/show/P3537

    有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 ( 1n1 000 ) 

    Those items are described in the nn lines that follow.

    c a b(1ci1 000 ,1ai<bi10e9 )

    p (1p1 000 000 ),

    m k s 1m,j10^9 , 1kj, sj100 000

    输出格式:

    For each plan put forward by the gang determine if it is feasible, i.e., whether it is possible to steal items of total worth exactly k_jkj and escape before anyone asks for their belongings.

    If the plan is feasible, your program should print the word TAK (Polish for yes) on the standard output, otherwise it should print NIE (Polish for no).

    输入输出样例

    输入样例#1: 复制
    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
    输出样例#1: 复制
    TAK
    NIE
    TAK
    TAK
    NIE

    题解:离线

    我们把所有的 mm 和所有的ai 从小到大排序,然后就是一个背包问题了,因为这样我们做到一边把物品放入背包一边去处理这个询问。

    定义fi 表示当物品的和为 i 时在所有的方案中,使得最小的 b 最大的方案中的 b 值。(这话有些绕口)

    然后接下来我们只要判断一下 fi 是否大于m+s 即可。

    注意边界问题,我开始漏算了M巨大时的情况,和今天早上一样算了还=后面一截

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1005, M = 1000005;
    #define For(a, b, c) for(int a = b; a <= c; a++)
    struct Point{int a, b, c;}p[N];
    struct Query{int m, s, k, id;}q[M];
    bool cmp1(Point A, Point B){
        return A.a < B.a;
    }
    bool cmp2(Query A, Query B){
        return A.m < B.m;
    }
    int ans[M], dp[M];
    int main(){
        
        //freopen("dt.in","r",stdin);
        //freopen("my.out","w",stdout);
        int m, n;
        scanf("%d", &n);
        For(i, 1, n)scanf("%d%d%d", &p[i].c, &p[i].a, &p[i].b);
        sort(p+1, p+1+n, cmp1);
        scanf("%d", &m);
        For(i, 1, m)scanf("%d%d%d", &q[i].m, &q[i].k, &q[i].s), q[i].id = i;
        sort(q+1, q+1+m, cmp2);
        dp[0] = 1e9 + 100;
        int nlst = 1, lst = 1;
        int limit = q[1].m;
        p[n+1].a = dp[0];
        bool fg = 0;
        int j;
        for(int i = nlst; i <= n;){
            //cout<<i<<" "<<nlst<<endl;
            while(p[i].a <= limit){
                for(int j = 100000; j >= p[i].c; j--)
                    dp[j] = max(dp[j], min(dp[j - p[i].c], p[i].b));
                i++;
            }
            nlst = i;
            for( j = lst; q[j].m == q[lst].m; j++){
                int id = q[j].id;
                if(q[j].m + q[j].s < dp[q[j].k])ans[id] = 1;
                //else ans[id] = -1;
            }
            lst = j; limit = q[lst].m;
            if(lst == m + 1)break;
            //fprintf(stderr, "%d
    ", lst);
        }
        for( ; j <= m; j++)
            if(dp[q[j].k] > q[j].m + q[j].s)ans[q[j].id] = 1;
        for(int i = 1; i <= m; i++)
            if(ans[i] == 1)puts("TAK");
            else puts("NIE");
         
    }
    View Code
  • 相关阅读:
    Google Authentication 机制原理
    ldap日志
    ldap + kerberos 整合
    kerberos
    U盘格式化后的恢复
    初始化脚本(Os_Init_Optimization.sh)
    拿到新机器,进行初始化和部署Nginx的过程
    python 列表生成式
    python 装饰器
    简单总结无线CPE、无线AP、无线网桥的不同之处【转】
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/9483305.html
Copyright © 2011-2022 走看看