
CF1475-D. Cleaning the Phone
发布日期:2021-05-13 02:07:43
浏览次数:10
分类:博客文章
本文共 2048 字,大约阅读时间需要 6 分钟。
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#include #include #include #include typedef long long ll;const ll INF = 0x3f3f3f3f3f3f3f3f;const int Maxn = 200005;ll a[Maxn];std::vector b1, b2;std::vector 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 ()); std::sort(b2.begin(), b2.end(), std::greater ()); 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;}
发表评论
最新留言
第一次来,支持一个
[***.219.124.196]2025年05月01日 00时33分33秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
postman怎么设置cookie共享
2019-03-11
oracle中duplicate column name异常处理
2019-03-11
linux 查看log日志相关命令
2019-03-11
linux 脚本 crontab 定时删除清理日志
2019-03-11
实用的 s t l
2019-03-11
IDEA 2019 安装 mybatis-plus插件
2019-03-11
JSON、JSONObject、JavaBean三者的相互转换
2019-03-11
JS 判断空字符串
2019-03-11
div 实现光标悬停变成手型
2019-03-11
vue项目 npm ERR! missing script: dev
2019-03-11
layer.confirm 无效
2019-03-11
Java 回调机制
2019-03-11
明明获取权限成功,为什么相机还是黑屏?
2019-03-11
Java文件编译运行流程
2019-03-11
springboot统一异常处理
2019-03-11
看完豁然开朗!2021年阿里Java高级面试题及答案,热度飙升!
2019-03-11
缓和曲线01——缓和曲线概论
2019-03-11
疲劳检测代码
2019-03-11