题目传送门

https://lydsy.com/JudgeOnline/problem.php?id=2802

题解

我一开始想到了一个比较麻烦的做法。

把每一天按照 \(b_i\) 从小到大排序,\(b_i\) 小的优先选。然后扣除库存的话,优先扣除在当前这个 \(b_i\) 的位置前面最近的库存。

这个可以使用树状数组来判断能不能选,然后扣除库存的时候因为每一个日子的库存只会被扣光一次,所以可以暴力跳,但是不要走已经被扣光的点,所以使用并查集跳过这些不应该经过的点。

但是很显然这个做法很麻烦,写起来细节和码量应该都不小。


所以我们不妨换一个做法。但是我实在想不到除了我上面的做法以外还有别的什么做法。

所以去拜读了一下题解。捂脸

大概意思就是说,我们很显然会有一个非常错误的做法:对于每一位能选就选。

使这个算法错误的情况是有可能存在一个点,选了当前这个以后可能会导致后面多于一个可选方案失效。(贪心策略很多时候成立的条件是以一换一

但是不要轻易放弃这个做法!

我们想一想怎么更正这个做法。

如上文所述,使这个算法错误的情况是有可能存在一个点,选了当前这个以后可能会导致后面多于一个可选方案失效。那么我们是不是可以找出一个方法把失效方案重新变得有效呢。

既然贪心策略很多时候成立的条件是以一换一,那么我们其实可以在当前这个点不选的时候,把这个东西和目前已经选过的最大的需求量比较。如果当前这个小的话,我们其实可以把当前这个拿去替换掉之前的最大的,因为这样一定可以使剩下的总库存变大。

至于之前的最大的需求量怎么找,就是用一个堆来维护一下。


上面两个做法的时间复杂度都是 \(O(n\log n)\)。

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;} typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii; template<typename I> inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
} const int N = 250000 + 7; int n;
int a[N], b[N], aa[N];
std::priority_queue<pii> q; inline void work() {
ll sum = 0;
int ans = 0;
for (int i = 1; i <= n; ++i) {
sum += a[i];
if (sum >= b[i]) sum -= b[i], q.push(pii(b[i], i));
else if (!q.empty() && sum + q.top().fi >= b[i] && b[i] <= q.top().fi) sum += q.top().fi - b[i], q.pop(), q.push(pii(b[i], i));
}
while (!q.empty()) aa[++ans] = q.top().se, q.pop();
std::sort(aa + 1, aa + ans + 1);
printf("%d\n", ans);
for (int i = 1; i <= ans; ++i) printf("%d%c", aa[i], " \n"[i == ans]);
} inline void init() {
read(n);
for (int i = 1; i <= n; ++i) read(a[i]);
for (int i = 1; i <= n; ++i) read(b[i]);
} int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}

bzoj2802 [Poi2012]Warehouse Store 贪心+堆的更多相关文章

  1. 【bzoj2802】[Poi2012]Warehouse Store 贪心+堆

    题目描述 有一家专卖一种商品的店,考虑连续的n天.第i天上午会进货Ai件商品,中午的时候会有顾客需要购买Bi件商品,可以选择满足顾客的要求,或是无视掉他.如果要满足顾客的需求,就必须要有足够的库存.问 ...

  2. BZOJ2802: [Poi2012]Warehouse Store

    2802: [Poi2012]Warehouse Store Time Limit: 10 Sec  Memory Limit: 64 MBSec  Special JudgeSubmit: 121  ...

  3. [bzoj2802][Poi2012]Warehouse Store_贪心_堆

    Warehouse Store bzoj-2802 Poi-2012 题目大意:一家商店的连续n天内,每一天会进货$a_i$个,有且只有一个客人回来买$b_i$个,问至多满足多少人. 注释:$1\le ...

  4. BZOJ2802 [Poi2012]Warehouse Store 【贪心】

    题目链接 BZOJ2802 题解 这样的问题通常逆序贪心 每个\(A[i]\)只能用来满足后面的\(B[i]\) 就用当前\(A[i]\)不断提供给最小的\(B[i]\)即可 用一个堆维护 #incl ...

  5. BZOJ2802——[Poi2012]Warehouse Store

    1.题目巨短,自己看看吧 2.分析:这道题,想了半天dp还是想不到,最后看题解发现是个贪心的思想,我们维护一个堆,如果这个人不能加入就把他和堆上最大的进行比较,然后搞搞就行了 #include < ...

  6. 【BZOJ 2802】 2802: [Poi2012]Warehouse Store (贪心)

    2802: [Poi2012]Warehouse Store Description 有一家专卖一种商品的店,考虑连续的n天.第i天上午会进货Ai件商品,中午的时候会有顾客需要购买Bi件商品,可以选择 ...

  7. bzoj 2802 [Poi2012]Warehouse Store STL

    [Poi2012]Warehouse Store Time Limit: 10 Sec  Memory Limit: 64 MBSec  Special JudgeSubmit: 621  Solve ...

  8. 【BZOJ】2802: [Poi2012]Warehouse Store(贪心)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2802 自己yy了一下... 每一次如果够那么就买. 如果不够,考虑之前买过的,如果之前买过的比当前花 ...

  9. BZOJ_2802_[Poi2012]Warehouse Store_堆+贪心

    BZOJ_2802_[Poi2012]Warehouse Store_堆+贪心 Description 有一家专卖一种商品的店,考虑连续的n天. 第i天上午会进货Ai件商品,中午的时候会有顾客需要购买 ...

随机推荐

  1. jvm内存模型学习心得

    昨天面试了两家,备受打击,问的多的就是jvm内存,然额真的是一头雾水.工作中用到的真是少之又少,面试还得问道, 今天恶补了下,在此作以下总结: jvm分为5部分 1.程序计数器 jvm支持多线程运行, ...

  2. Java synchronized到底锁住的是什么?

    使用环境:多线程java程序中. 作用:在多线程的环境下,控制synchronized代码段不被多个线程同时执行.synchronized既可以加在一段代码上,也可以加在方法上. 使用:synchro ...

  3. JWT原理和使用

    jwt JSON Web Tokens,是一种开发的行业标准RFC 7519,用于安全的表示双方之间的声明.目前,jwt广泛的用在系统的用户认证方面,特别是前后端分离项目. 1.jwt认证流程 在项目 ...

  4. Ajax请求Json数据,报500错误,后台没有错误日志。

    post请求:http://localhost:9080/DataDiscoveryWeb/issueformcount/queryIssueTendencyDetail.xhtml?jobId=86 ...

  5. 中国MOOC_面向对象程序设计——Java语言_期末考试编程题_1细胞自动机

    期末考试编程题 返回   这是期末考试的编程题 温馨提示: 1.本次考试属于Online Judge题目,提交后由系统即时判分. 2.学生可以在考试截止时间之前提交答案,系统将取其中的最高分作为最终成 ...

  6. python3 基本数据类型_2

    #!/usr/bin/python3 #以下set,dict的方法py2无法运行 #创建set 集合,使用大括号 { } 或者 set() 函数创建 #注意:创建一个空集合必须用 set() 而不是 ...

  7. LAMP框架

    一基本常识 LNMP (Linux + Nginx + MySQL + PHP) LAMP (Linux + Apache + MySQL + PHP) //php作为Apache的模块Apache. ...

  8. pymysql操作数据库

    pymysql.connect()参数说明:(连接数据库时需要添加的参数)host(str): MySQL服务器地址port(int): MySQL服务器端口号user(str): 用户名passwd ...

  9. kafka消费者脚本无法启动问题

    console-consumer can't rebalance after 4 retries 解决方案:kafka0.9版本换成1.0版本 究竟是怎么回事我也不知道

  10. 剑指Offer编程题(Java实现)——链表中环的入口结点

    题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. 思路一 迭代遍历链表,利用HashSet将每个结点添加到哈希表中,如果添加失败(重复遍历了这个结点即遇到环),输出 ...