LOJ#2306 蔬菜


补充一个题意不太清楚的地方:蔬菜坏掉是假设蔬菜都有标号,那么特定标号的蔬菜就会在特定时间坏掉。如果你及时卖了它们,那么那一天就不会有新的蔬菜坏掉。
结论1:如果我们知道了k天的答案,那么我们直接扔掉若干个最小的蔬菜即可获得k - 1天的答案。
证:因为能在k天卖的一定能在k - 1天卖.....
推论1:只要求100000天卖哪些蔬菜即可。
结论2:最贵的菜越晚卖越好。
证:因为它最贵,所以是一定要卖的。我们要让别的菜尽量卖的多,晚卖有决策包容性。
推论2:按照从贵到廉考虑蔬菜,每个菜越晚卖越好。
结论3:可以把每个蔬菜按照变质天数分类,当天变质的蔬菜能够出售的时间是第一天到当天。
推论3:假如把每种菜按照变质天数分类,那么有额外奖励的蔬菜应该在最后一天。
证:因为额外奖励比正常蔬菜贵,所以一定会优先卖它。由结论2可知应放在最后。
然后算法就出来了。分类之后按顺序放蔬菜。每天维护从它开始向前,第一个空闲的地方。可以用并查集实现。
每天能放多少菜要特别注意,代码实现上我用总数 - 之前应该留下的菜数来限制。
#include <bits/stdc++.h>
inline char gc() {
/*static char buf[1000000], *p1, *p2;
if(p1 == p2) p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin);
return (p1 == p2) ? EOF : *p1++;*/ return getchar();
}
template <class T> inline void read(T &x) {
x = ;
char c = gc();
bool f = ;
while(c < '' || c > '') {
if(c == '-') f = ;
c = gc();
}
while(c >= '' && c <= '') {
x = x * + c - ;
c = gc();
}
if(f) x = (~x) + ;
return;
}
typedef long long LL;
const int N = ;
struct Node {
int val, d, id, cnt, flag;
Node(int V = , int D = , int ID = , int C = , int F = ) {
val = V;
d = D;
id = ID;
cnt = C;
flag = F;
}
inline bool operator <(const Node &w) const {
if(val != w.val)
return val < w.val;
return d < w.d;
}
};
std::priority_queue<Node> Q, Q2;
int a[N], s[N], c[N], x[N], fa[N], rest[N];
LL ans[N];
int find(int x) {
if(x == fa[x]) return x;
return fa[x] = find(fa[x]);
}
inline void del(LL &a) {
Node t = Q2.top();
Q2.pop();
a += t.val;
t.cnt--;
if(t.cnt) Q2.push(t);
return;
}
int main() {
int n, m, k, lm = ;
read(n); read(m); read(k);
for(int i = ; i <= lm; i++) {
fa[i] = i;
rest[i] = m;
}
for(int i = ; i <= n; i++) {
read(a[i]); read(s[i]); read(c[i]); read(x[i]);
LL day;
if(!x[i]) {
day = lm;
}
else {
day = std::min((c[i] - ) / x[i] + , lm);
}
Q.push(Node(a[i] + s[i], day, i, , ));
if((day - ) * x[i] + < c[i]) { /// the last day have rest
Q.push(Node(a[i], day, i, c[i] - - x[i] * (day - ), ));
}
if(day > && x[i]) {
Q.push(Node(a[i], day - , i, x[i] * (day - ), ));
}
//c[i]--;
}
//int Last = 0, Cnt = 0;
int tot = ;
while(Q.size()) {
Node t = Q.top();
Q.pop();
int now = find(t.d);
while(now && t.cnt) {
LL large;
if(t.flag) large = std::min(t.cnt, std::min(t.cnt - x[t.id] * (now - ), rest[now]));
else if(x[t.id]) large = std::min(t.cnt, std::min(x[t.id], rest[now]));
else large = std::min(t.cnt, rest[now]);
ans[lm] += t.val * large;
tot += large;
Q2.push(Node(-t.val, , t.id, large));
rest[now] -= large;
t.cnt -= large;
if(!rest[now]) {
fa[now] = find(now - );
}
now = find(now - );
}
}
int day = (tot - ) / m + ; /// need (day) to sell the vegetables
for(int i = lm - ; i >= day; i--) {
ans[i] = ans[lm];
}
ans[day - ] = ans[day];
for(int T = ; T <= tot - m * (day - ); T++) {
del(ans[day - ]);
}
for(int i = day - ; i >= ; i--) {
ans[i] = ans[i + ];
for(int T = ; T <= m; T++) {
del(ans[i]);
}
}
for(int i = ; i <= k; i++) {
int t;
read(t);
printf("%lld\n", ans[t]);
}
return ;
}
AC代码
LOJ#2306 蔬菜的更多相关文章
- *LOJ#2306. 「NOI2017」蔬菜
$n \leq 100000$种蔬菜,每个蔬菜有:一单位价格:卖第一单位时额外价格:总量:每天腐烂量.每天能卖$m \leq 10$单位蔬菜,多次询问:前$k \leq 100000$天最多收入多少. ...
- 【LOJ】#2306. 「NOI2017」蔬菜
题解 从后往前递推 如果我们知道了第i天的最优方案和第i天选择的蔬菜,加入第i天选择的蔬菜数量为S,我们只需要减去最小的S - (i - 1) * M 个蔬菜即可 所以我们只要求出最后一天的蔬菜选择 ...
- bzoj4946 Noi2017 蔬菜
题目描述 小 N 是蔬菜仓库的管理员,负责设计蔬菜的销售方案. 在蔬菜仓库中,共存放有nn 种蔬菜,小NN 需要根据不同蔬菜的特性,综合考虑各方面因素,设计合理的销售方案,以获得最多的收益. 在计算销 ...
- [Noi2016]区间 BZOJ4653 洛谷P1712 Loj#2086
额... 首先,看到这道题,第一想法就是二分答案+线段树... 兴高采烈的认为我一定能AC,之后发现n是500000... nlog^2=80%,亲测可过... 由于答案是求满足题意的最大长度-最小长 ...
- Loj #2192. 「SHOI2014」概率充电器
Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...
- Loj #3096. 「SNOI2019」数论
Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...
- Loj #3093. 「BJOI2019」光线
Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...
- Loj #3089. 「BJOI2019」奥术神杖
Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...
- Loj #2542. 「PKUWC2018」随机游走
Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...
随机推荐
- php redis常用方法代码例子
1,connect 描述:实例连接到一个Redis.参数:host: string,port: int返回值:BOOL 成功返回:TRUE;失败返回:FALSE 示例: <?php $redis ...
- WPF中如何为ItemsControl添加ScrollViewer并显示ScrollBar
今天在开发的过程中突然碰到了一个问题,本来的意图是想当ItemsControl中加载的Item达到一定数量时,会出现ScrollViewer并出现垂直的滚动条,但是实际上并不能够达成目标,对于熟手来说 ...
- Best Chrome Extensions
Best Chrome Extensions chrome://extensions/ # ghelper chrome-extension://cieikaeocafmceoapfogpffaalk ...
- How to install macOS Sierra on Skylake
create usb installer sudo /Applications/Install\ macOS\ Sierra.app/contents/resources/createinstallm ...
- bzoj5358
Problem A. 口算训练Input file: stdinOutput file: stdoutTime limit: 5 secondsMemory limit: 512 megabytes小 ...
- hdu-1421(dp)
解题思路:dp[i][j]表示前i个物品中取k对所要的最小花费: 首先得对物品进行处理,因为需要当前物品减前一个物品的平方和最小: 所以先排序,因为排序的相邻两个的差的平方一定最小: 然后转移方程:d ...
- Civil 3D 2017本地化中VBA程序移植到2018版中
中国本地化包简直就是一块鸡肋, 但对于某些朋友来说还真离不了: 可惜中国本地化包的推出一直滞后, 在最新版软件出来后1年多, 本地化还不一定能够出来, 即使出来了, 也只能是购买了速博服务的用户才能得 ...
- 1、linux下对绝对路径和相对路径
cd / 回到根目录 cd /etc 回到根目录下的etc 目录下 绝对路径 路径写法是从根目录/ 写起来的. cd . 当前目录 cd .. 上层目录 cd ~回到自家的根目 ...
- 添加一个Android框架层的系统服务与实现服务的回调
2017-10-09 概述 所谓Android系统服务其本质就是一个通过AIDL跨进程通信的小Demo的延伸而已.按照 AIDL 跨进程通信的标准创建一套程序,将服务端通过系统进程来运行实现永驻内存, ...
- BZOJ1823[JSOI2010]满汉全席——2-SAT+tarjan缩点
题目描述 满汉全席是中国最丰盛的宴客菜肴,有许多种不同的材料透过满族或是汉族的料理方式,呈现在數量繁多的菜色之中.由于菜色众多而繁杂,只有极少數博学多闻技艺高超的厨师能够做出满汉全席,而能够烹饪出经过 ...