• 1122考试T2


    1122考试T2

    ​ 题目大意:

    ​ 有(n)个物品需要被运走, 每个物品都有两个属性值(w,s). 现在有两种车, 第一种车有(A)辆, 可以运送(w)严格小于(x_i)的物品, 对(s)不做要求.第二种车有(B)辆可以运送(s)严格小于(y_i)的物品,对(w)不做要求.每个车子运送一个物品需要花费1的时间. 问最短多长时间可以把所有物品运送完.如果不可能运送完则输出"-1".

    (n <= 1e6, A, B <= 50000).

    ​ 二分 + 贪心 + 优先队列.

    ​ 将(x_i)从小到大排序, 将(y_i)从大到小排序, 将物品按(w)为第一关键字, (s)为第二关键字从小到大排序.

    ​ 我们二分最短多长时间可以把所有物品运送完.也就是每个车子最多可以运送多少物品.

    ​ 然后我们把物品都给第一种车, 贪心策略是是(w)小的尽量给(x)小的车子, 这样可以尽可能多的放.

    ​ 然后会剩下一些物品, 我们把它们投到一个大根堆里, 按(s)从大到小排序, 然后把这些物品往第二种车里放.

    ​ 如果说(s_i >= y_i), 也就是说当前第二种车无法装下这个物品, 那么后面的车子肯定也无法装下, 因为已经按(y_i)从大到小排序了.

    ​ 最后在判断一下队列里是否为空, 如果说不为空, 说明当前这个二分的值小了, 无法运完所有物品, 那么就增大这个二分的值, 反之则减小这个二分的值.

    #include <bits/stdc++.h>
    
    using namespace std;
    
    inline long long read() {
    	long long s = 0, f = 1; char ch;
    	while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
    	for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
    	return s * f;
    }
    
    const int N = 1e6 + 5, M = 5e4 + 5;
    int A, B, n, ans;
    int a[M], b[M];
    struct bag { int w, s; } c[N];
    
    int cmp(int a, int b) { return a > b; }
    
    int mmp(bag a, bag b) { return a.w == b.w ? a.s < b.s : a.w < b.w; }
    
    int check(int t) {
    	priority_queue <int> q;
    	int p = 1;
    	for(int i = 1;i <= A; i++) {
    		while(p <= n && c[p].w < a[i]) { q.push(c[p].s); p ++; }
    		for(int j = 1;j <= t && !q.empty(); j++) q.pop();
    	}
    	while(p <= n) { q.push(c[p].s); p ++; }
    	for(int i = 1;i <= B; i++) {
    		for(int j = 1;j <= t && !q.empty(); j++) 
    			if(q.top() >= b[i]) return 0;
    			else q.pop();
    	}
    	return q.empty();
    }
    
    int main() {
    
    	A = read(); B = read(); n = read();
    	for(int i = 1;i <= A; i++) a[i] = read(); 
    	for(int i = 1;i <= B; i++) b[i] = read();
    	for(int i = 1;i <= n; i++) c[i].w = read(), c[i].s = read();
    	sort(a + 1, a + A + 1); sort(b + 1, b + B + 1, cmp); sort(c + 1, c + n + 1, mmp);
    	int l = 1, r = n, mid;
    	while(l <= r) {
    		mid = (l + r) >> 1;
    		if(check(mid)) r = mid - 1, ans = mid;
    		else l = mid + 1;
     	}
     	if(!check(ans)) printf("-1"); else printf("%d", ans);
    
    	return 0;
    }
    
  • 相关阅读:
    Android ANR原因以及开发时如何预防
    Nmon工具的使用以及通过nmon_analyse生成分析报表
    LInux在线安装JDK
    linux使用JMETER进行分布式压力测试
    Jmeter-调整占用内存解决内存溢出
    参数化之利用CSV Data Set Config从文件读取参数并关联变量
    JMETER 定时器 之 常数吞吐量定时器
    【Jmeter】Jmeter聚合报告分析
    Nmon的安装及使用
    MySQL CURDATE() 函数
  • 原文地址:https://www.cnblogs.com/czhui666/p/14021647.html
Copyright © 2020-2023  润新知