4946: [Noi2017]蔬菜

http://www.lydsy.com/JudgeOnline/upload/Noi2017D2.pdf

分析:

  贪心。

  首先可以将一个蔬菜拆成两个,一个是有加成的,一个是没有加成的。

  贪心:1、多卖出些贵的好,所以先考虑贵的蔬菜;2、对于一个蔬菜,卖的越晚越好(越晚,可以给前面留出位置。)

  然后对蔬菜按价格排序,从后往前考虑卖的时间,尽量卖。如果一天的m个蔬菜全卖了,那么下次走到这个位置就没用了,所以直接并查集合并即可。所以复杂度是$O(mn \times 并查集的复杂度)$。现在可以贪心的处理出任意天的最大买的获益。

  如果对于每次询问都这样做,显然会超时。考虑优化。如果知道某一天,是否可以快速的知道相邻的一天。 

  正着考虑,每次加入一些位置,因为上面的贪心是从最后一天贪心的,现在最后一天变了,所以无法推出下一天,没有什么关系。

  正难则反,反过来考虑,每次相当于减去一些蔬菜,所以可以减去最便宜的。

  做法:用上面的贪心处理处n天的最大获益,并记录每天卖了多少,用栈记录所有卖的蔬菜(上面的一定是价值小的),然后计算这一天需要减去多少颗蔬菜,从栈顶开始减。复杂度$O(n+D)$。

代码:

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream>
#include<cctype>
#include<set>
#include<vector>
#include<queue>
#include<map>
#define fi(s) freopen(s,"r",stdin);
#define fo(s) freopen(s,"w",stdout);
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ; struct Node{
int w, siz, sub, d; // 价值,数量,每天减少的,消失的一天
Node() {}
Node(int _w,int _siz,int _sub,int _d) { w = _w, siz = _siz, sub = _sub, d = _d; }
bool operator < (const Node &A) const {
return w > A.w;
}
}A[N];
int n, m, k, Top;
int sk[N], skw[N], d[N], fa[N], q[N];
LL ans[N], sumr[N], del[N], Sum; int find(int x) {
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
void Merge(int a,int b) {
a = find(a), b = find(b);
if (a != b) fa[a] = b;
}
void Calc(int i,int s,int w) { // 第i天,卖价值为w的菜,卖了s个
Sum += 1ll * s * w;
d[i] += s;
sk[Top] += s, skw[Top] = w; // skw[Top]+=w!!!
if (d[i] == m) Merge(i, i - );
}
int main() {
n = read(), m = read(), k = read();
int tot = , D = ;
for (int i=; i<=n; ++i) {
int w = read(), fir = read(), siz = read(), sub = read();
A[++tot] = Node(w + fir, , , sub ? (siz - ) / sub + : N - );
if (--siz) A[++tot] = Node(w, siz, sub, sub ? (siz - ) /sub + : N - );
}
for (int i=; i<=k; ++i)
q[i] = read(), D = max(q[i], D); sort(A + , A + tot + );
for (int i=; i<=D; ++i) fa[i] = i;
for (int i=; i<=tot; ++i) {
++Top;
int idx = find(min(A[i].d, D));
int sum = (idx - ) * A[i].sub, r = A[i].siz - sum; // sum前面卖的,r现在卖的
while (idx && r) {
int mn = min(m - d[idx], r); // d[idx] not d[idx - 1]
Calc(idx, mn, A[i].w);
r -= mn;
int p = idx;
idx = find(idx - );
p -= idx;
if (sum) r += p * A[i].sub, sum -= p * A[i].sub; //!!!
}
if (!find(D)) break;
}
for (int i=; i<=D; ++i) sumr[i] = sumr[i - ] + m - d[i]; // 剩余的前缀和
LL tmp = ;
for (int i=D; i>=; --i) del[i] = max(tmp - sumr[i], 0ll), tmp += d[i]; // 到第i天要删除的个数
for (int i=D; i>=; --i) {
ans[i] = Sum;
int now = del[i - ] - del[i]; // 从第i天到第i-1天,要减去多少蔬菜。
while (now) {
int mn = min(now, sk[Top]);
Sum -= 1ll * skw[Top] * mn;
now -= mn;
sk[Top] -= mn;
if (!sk[Top]) Top --;
}
}
for (int i=; i<=k; ++i) printf("%lld\n",ans[q[i]]);
return ;
}

4946: [Noi2017]蔬菜的更多相关文章

  1. 【刷题】BZOJ 4946 [Noi2017]蔬菜

    Description http://www.lydsy.com/JudgeOnline/upload/Noi2017D2.pdf Solution 网上大部分都是并查集写法,但是有大神写了非并查集写 ...

  2. BZOJ.4946.[NOI2017]蔬菜(贪心 离线)

    题目链接 因为有删除,考虑倒序处理某个p的询问. 那么每天删除xi的蔬菜就变成了每天运来xi的蔬菜.那么我们取当前最优的即可,早取晚取都一样,不需要留给后面取,还能给后面更优的留出空间. 这样就只需考 ...

  3. [NOI2017]蔬菜

    [NOI2017]蔬菜 题目描述 大意就是有\(n\)种物品,第\(i\)个物品有\(c_i\)个,单价是\(a_i\).然后每天你可以卖出最多\(m\)个物品.每天结束后第\(i\)种物品会减少\( ...

  4. BZOJ4946[Noi2017]蔬菜——线段树+堆+模拟费用流

    题目链接: [Noi2017]蔬菜 题目大意:有$n$种蔬菜,每种蔬菜有$c_{i}$个,每种蔬菜每天有$x_{i}$个单位会坏掉(准确来说每天每种蔬菜坏掉的量是$x_{i}-$当天这种蔬菜卖出量), ...

  5. 【BZOJ4946】[NOI2017]蔬菜(贪心)

    [BZOJ4946][NOI2017]蔬菜(贪心) 题面 BZOJ 洛谷 UOJ 题解 忽然发现今年\(NOI\)之前的时候切往年\(NOI\)的题目,就\(2017\)年的根本不知道怎么下手(一定是 ...

  6. bzoj4946: [Noi2017]蔬菜 神烦贪心

    题目链接 bzoj4946: [Noi2017]蔬菜 题解 挺神的贪心 把第次买的蔬菜拆出来,记下每种蔬菜到期的日期,填第一单位蔬菜比其他的要晚 按价格排序后,贪心的往前面可以填的位置填就可以了.找可 ...

  7. [NOI2017]蔬菜 贪心

    题面: [NOI2017]蔬菜 题解: 首先每天蔬菜会变质这点并不好处理,我们考虑让时间倒流,从后向前处理,这样的话就相当于每天都会得到一定量的蔬菜. 这样做有什么好处呢? 我们可以发现一个性质:如果 ...

  8. BZOJ4946 & 洛谷3826 & UOJ318:[NOI2017]蔬菜——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4946 https://www.luogu.org/problemnew/show/P3826 ht ...

  9. bzoj4946 Noi2017 蔬菜

    题目描述 小 N 是蔬菜仓库的管理员,负责设计蔬菜的销售方案. 在蔬菜仓库中,共存放有nn 种蔬菜,小NN 需要根据不同蔬菜的特性,综合考虑各方面因素,设计合理的销售方案,以获得最多的收益. 在计算销 ...

随机推荐

  1. whoami

    功能说明:显示当前登录的用户名,.

  2. BZOJ3143:[HNOI2013]游走(高斯消元)

    Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点, ...

  3. [JSOI2016]最佳团体

    嘟嘟嘟 01分数规划+树形背包. 然后就没了. 结果我调了半天,原因还是树形背包不熟练. 我是用dfs序求的,转化的时候,是dp[i][j]转化到dp[i + 1][j + 1]或dp[i +siz[ ...

  4. TCP建立连接和释放连接过程

    TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议.TCP建立连接需要三次握手,释放连接需要四次握手. 1.TCP整 ...

  5. Url快捷方式转超链接页

    效果:(打了码  可以感受到效果) 问题: 近期发现了之前的一些网页快捷方式文件有50个  查看起来实在不方便 解决: 目前想到了两种 (书签法) (类书签法) 第一种简单快速 (当然有掌握写技巧) ...

  6. Coursera机器学习基石 第2讲:感知器

    第一讲中我们学习了一个机器学习系统的完整框架,包含以下3部分:训练集.假设集.学习算法 一个机器学习系统的工作原理是:学习算法根据训练集,从假设集合H中选择一个最好的假设g,使得g与目标函数f尽可能低 ...

  7. springmvc错误集锦-dubbo包含低版本的spring包,依赖的时候应该排除Caused by: java.lang.reflect.MalformedParameterizedTypeException

    dubbo 常见错误 1. Caused by: java.lang.reflect.MalformedParameterizedTypeException 启动时报错,原因是dubbo 依赖 spr ...

  8. java GC是何时对什么东西做什么事情

    之前学习了javaGC的原理机制,有了一定的了解,现在做一个整理总结,便于理解记忆,包括三个问题: 1. java GC是什么时候做的? 2. java GC作用的东西是什么? 3. java GC具 ...

  9. performPeriodicTask

    /********************************************************************* * @fn performPeriodicTask 执行 ...

  10. Office365学习笔记—列表查询,删除条目,更新条目。

    1,基于Query语句的列表查询. function retrieveListItems(itemId) { var siteUrl=_spPageContextInfo.webServerRelat ...