zoukankan      html  css  js  c++  java
  • 背包问题 [二维偏序, 树状数组]

    背包问题


    color{red}{正解部分}

    二维偏序问题,

    将所 有点 按照 vv 为第一关键字, ww 为第二关键字 从大到小 排序,

    从前往后扫, 离散化坐标, 使用 树状数组 维护 yy前缀最大值, 记为 max_curmax\_cur

    对于背包的限制, 将背包按容量 从大到小 排序, 维护一个指针从左往右根据物品的容量往右移动, 记为 tt,

    背包从容量大的开始选显然是最优的 .

    min(t,max_cur)min(t, max\_cur) 更新 .


    color{red}{实现部分}

    #include<bits/stdc++.h>
    #define reg register
    
    int read(){
            char c;
            int s = 0, flag = 1;
            while((c=getchar()) && !isdigit(c))
                    if(c == '-'){ flag = -1, c = getchar(); break ; }
            while(isdigit(c)) s = s*10 + c-'0', c = getchar();
            return s * flag;
    }
    
    const int maxn = 1e5 + 5;
    
    int N;
    int M;
    int Len_2;
    int rl[maxn];
    int B2[maxn];
    
    struct Node{ int w, v; } A[maxn];
    
    bool cmp(Node a, Node b){ return a.w==b.w?a.v>b.v:a.w>b.w; }
    
    struct Bit_Tree{
            int v[maxn], lim;
            void Add(int k, int x){ while(k<=lim)v[k]=std::max(v[k], x), k+=k&-k; }
            int Query(int k){ int s = 0; while(k){ s = std::max(v[k], s); k -= k&-k; } return s; }
    } bit_t;
    
    void Work(){
            N = read();
            for(reg int i = 1; i <= N; i ++) A[i].w = read(), B2[i] = A[i].v = read();
            std::sort(A+1, A+N+1, cmp);
            std::sort(B2+1, B2+N+1), Len_2 = std::unique(B2+1, B2+N+1) - B2-1;
            for(reg int i = 1; i <= N; i ++) A[i].v = std::lower_bound(B2+1, B2+Len_2+1, A[i].v)-B2;
            M = read(); 
            for(reg int i = 1; i <= M; i ++) rl[i] = read();
            std::sort(rl+1, rl+M+1, std::greater<int>());
            int t = 0, Ans = 0;
            bit_t.lim = Len_2; memset(bit_t.v, 0, sizeof bit_t.v);
            for(reg int i = 1; i <= N; i ++){
                    while(t < M && rl[t+1] >= A[i].w) t ++;
                    int p = bit_t.Query(Len_2-A[i].v+1), cur = std::min(t, p+1);
                    bit_t.Add(Len_2-A[i].v+1, cur); Ans = std::max(Ans, cur);
            }
            printf("%d
    ", Ans);
    }
    
    int main(){
            int T = read(); while(T --) Work();
            return 0;
    }
    
  • 相关阅读:
    “不裁员”才是公司度过艰难时期的聪明选择
    oracle服务端与客户端字符集不同导致中文乱码解决方案
    [转]ABAP数据库操作系列(5)
    [转]ABAP数据库操作系列(2)
    [转]整理的函数
    [转]ABAP数据库操作系列(6)
    [转]ABAP数据库操作系列(7)
    [转]Authoritycheck
    [转]ABAP Program to Display SAP Icons
    [转]ABAP数据库操作系列(3)
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822397.html
Copyright © 2011-2022 走看看