CF1475-D. Cleaning the Phone

题意:

手机上有很多应用非常占用内存,你要清理内存。对于每个应用\(i\)有以下描述:应用\(i\)占用了\(a_i\)的空间,它的方便度为\(b_i\)。

现在让你删除其中部分应用使得删除的应用占用的空间总大小大于等于\(m\)且损失的方便度最小。


思路:

按照方便度将应用分类,每一类按照应用占用的空间大小从大到小排序,之后将每一类应用占用空间的前缀和求出来。

依次枚举删除前\(j\)个方便度为\(1\)的应用,这时已经删除了的应用的总内存空间就是\(pre1[j_1]\),那么还要从方便度为\(2\)的应用中移除\(m-pre1[j_2]\)的空间,这时只需要用\(lower\_bound\)在\(pre2\)中找到这个值就可以了,这里设这个位置为\(j_2\)。每次枚举,它损失的总方便度为\(1*i+2*j\),在所用的情况中取最小的即可。


一些疑问:

1.为什么不都删除方便度为1的应用?

假如有四个应用,占用的空间分别为1,1,1,5,方便度分别为1,1,1,2,现在要m=3,观察一下就可以发现选那个方便度为\(2\)的应用损失的方便度反而更小。

2.为什么要按照方便度划分成两组?

分类之后数据更好处理。如果不划分可以通过内存/方便度的比值进行排序,从前往后加。但这样会出现一个棘手的问题:你从前往后加,加到第\(j\)个数字的时候总空间已经超过\(m\)了,但是第\(j\)个应用的方便度为\(2\),有没有发现问题?可能后面有一个应用,它的方便度为\(1\),虽让它的内存/方便度比第\(j\)个应用小,但是它已经完全可以让前\(j-1\)个应用的空间加上他的空间大小使得总大小大于等于\(m\),但是找这个数字很麻烦,而且会徒增复杂度。

上面复杂的描述已经可以说明问题,我们不想把简单的问题复杂化。


AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector> typedef long long ll; const ll INF = 0x3f3f3f3f3f3f3f3f;
const int Maxn = 200005; ll a[Maxn];
std::vector<ll>b1, b2;
std::vector<ll>pre1, pre2; void solve() {
int n;
ll m, t, sum = 0;
scanf("%d %lld", &n, &m);
for (int i = 0; i < n; i++) {
scanf("%lld", a + i);
sum += a[i];
}
b1.clear();
b2.clear();
for (int i = 0; i < n; i++) {
scanf("%lld", &t);
if (t == 1) {
b1.push_back(a[i]);
} else {
b2.push_back(a[i]);
}
}
if (sum < m) {
printf("-1\n");
return;
}
std::sort(b1.begin(), b1.end(), std::greater<ll>());
std::sort(b2.begin(), b2.end(), std::greater<ll>()); pre1.clear(); pre1.push_back(0); // 这里是因为有可能方便度为1的一个也不选
pre2.clear(); pre2.push_back(0); // 与上同理 for (int i = 1; i <= b1.size(); i++) {
t = pre1[i - 1] + b1[i - 1];
pre1.push_back(t);
}
for (int i = 1; i <= b2.size(); i++) {
t = pre2[i - 1] + b2[i - 1];
pre2.push_back(t);
}
ll ans = INF;
for (int i = 0; i < pre1.size(); i++) {
ll tar = m - pre1[i];
int p = std::lower_bound(pre2.begin(), pre2.end(), tar) - pre2.begin();
if (p == pre2.size()) {
continue;
}
ans = std::min(ans, (ll)(i + p * 2));
}
printf("%lld\n", ans);
} int main() {
int T;
scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}

CF1475-D. Cleaning the Phone的更多相关文章

  1. 【bzoj1672】[USACO2005 Dec]Cleaning Shifts 清理牛棚

    题目描述 Farmer John's cows, pampered since birth, have reached new heights of fastidiousness. They now ...

  2. Coursera-Getting and Cleaning Data-week1-课程笔记

    博客总目录,记录学习R与数据分析的一切:http://www.cnblogs.com/weibaar/p/4507801.html -- Sunday, January 11, 2015 课程概述 G ...

  3. Coursera-Getting and Cleaning Data-Week2-课程笔记

    Coursera-Getting and Cleaning Data-Week2 Saturday, January 17, 2015 课程概述 week2主要是介绍从各个来源读取数据.包括MySql ...

  4. Coursera-Getting and Cleaning Data-Week3-dplyr+tidyr+lubridate的组合拳

    Coursera-Getting and Cleaning Data-Week3 Wednesday, February 04, 2015 好久不写笔记了,年底略忙.. Getting and Cle ...

  5. Coursera-Getting and Cleaning Data-week4-R语言中的正则表达式以及文本处理

    博客总目录:http://www.cnblogs.com/weibaar/p/4507801.html Thursday, January 29, 2015 补上第四周笔记,以及本次课程总结. 第四周 ...

  6. 【BZOJ1672】[Usaco2005 Dec]Cleaning Shifts 清理牛棚 动态规划

    [BZOJ1672][Usaco2005 Dec]Cleaning Shifts Description Farmer John's cows, pampered since birth, have ...

  7. poj 2376 Cleaning Shifts

    http://poj.org/problem?id=2376 Cleaning Shifts Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  8. POJ 2376 Cleaning Shifts(轮班打扫)

    POJ 2376 Cleaning Shifts(轮班打扫) Time Limit: 1000MS   Memory Limit: 65536K [Description] [题目描述] Farmer ...

  9. POJ 2376 Cleaning Shifts 贪心

    Cleaning Shifts 题目连接: http://poj.org/problem?id=2376 Description Farmer John is assigning some of hi ...

  10. Bzoj 3389: [Usaco2004 Dec]Cleaning Shifts安排值班 最短路,神题

    3389: [Usaco2004 Dec]Cleaning Shifts安排值班 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 218  Solved: ...

随机推荐

  1. 【ORA】ORA-39002,ORA-39070,ORA-29283, ORA-06512,ORA-29283解决办法

    今天使用IMPDP导入的时候报了一个错误 ORA-39002: invalid operation  ORA-39070: Unable to open the log file.  ORA-2928 ...

  2. 爬虫-使用lxml解析html数据

    使用lxml之前,我们首先要会使用XPath.利用XPath,就可以将html文档当做xml文档去进行处理解析了. 一.XPath的简单使用: XPath (XML Path Language) 是一 ...

  3. [分享] 最流行的 10 个 JavaScript 库

    1. Lodash https://github.com/lodash/lodash 一个工具库,用得还蛮多. 2. Chalk https://github.com/chalk/chalk 给终端加 ...

  4. luoguP2016 战略游戏

    题目描述 Bob喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的办法.现在他有个问题.他要建立一个古城堡,城堡中的路形成一棵树.他要在这棵树的结点上放置最少数目的士兵,使得这些士兵能了 ...

  5. CSS不用背景图片实现优惠券样式反圆角,凹圆角,反向半圆角,并且背景渐变

    日常开发过程中,特别是商城相关应用开发过程中,时常会遇到花里胡哨的设计图,比如优惠券样式,上图: 实现思路如下:     1.先写一个外容器,实现背景色渐变: Html: 1 <div clas ...

  6. 3、wait和waitpid

    1. 函数介绍 wait函数:调用该函数使进程阻塞,直到任意一个子进程结束,或者该进程接收到了一个信号为止,如果该进程没有子进程或该进程的子进程已经结束,wait函数立即返回. waitpid函数:与 ...

  7. 糊糊的学习笔记--Fiddle抓包

    Fiddle简述 Fiddler是一个http调试代理,它能 够记录所有的你电脑和互联网之间的http通讯,Fiddler 可以也可以让你检查所有的http通讯,设置断点,以及Fiddle 所有的&q ...

  8. js中的事件委托(事件代理)详解

    本文转载:https://www.cnblogs.com/liugang-vip/p/5616484.html#!comments js中的事件冒泡.事件委托是js 中一些需要注意的小知识点,这里结合 ...

  9. 服务发现 ap cp 强一致性 最终一致性 dns vip ip

    为什么基于域名 08 | 服务发现:到底是要CP还是AP? https://time.geekbang.org/column/article/208171 为什么需要服务发现?先举个例子,假如你要给一 ...

  10. https://www.hutool.cn/ 糊涂

    一个Java基础工具类,对文件.流.加密解密.转码.正则.线程.XML等JDK方法进行封装,组成各种Util工具类,同时提供以下组件: 模块 介绍 hutool-aop JDK动态代理封装,提供非IO ...