题目链接

bzoj4946: [Noi2017]蔬菜

题解

挺神的贪心

把第次买的蔬菜拆出来,记下每种蔬菜到期的日期,填第一单位蔬菜比其他的要晚

按价格排序后,贪心的往前面可以填的位置填就可以了。找可以填的位置用并查集维护一下。这样就求出了最大天数的答案。

对于询问的答案,从最后一天往前推,把最便宜的那些丢掉就好了。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define gc getchar
#define pc putchar
#define int long long
inline int read() {
int x = 0,f = 1;
char c = getchar();
while(c < '0' || c > '9') c = gc();
while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = gc();
return x * f;
}
void print(int x) {
if(x < 0) {
pc('-'); x = -x;
}
if(x >= 10)print(x / 10);
pc(x % 10 + '0');
}
const int maxn = 200007;
int n,m,k;
struct node {
int a,d,c,x;
node(int a = 0,int c = 0,int x = 0,int d = 0) : a(a), c(c),x(x),d(d) {};
bool operator < (const node &k) const {
return a > k.a;
}
} a[maxn];
int tot = 0;
int q[maxn],fa[maxn];
int find(int x ) {
if(fa[x] != x) fa[x] = find(fa[x]);
return fa[x];
}
void unionn(int x,int y) {
int fx = find(x),fy = find(y);
if(fx == fy) return ;
fa[fy] = fx;
}
int cnt = 0;
int g[maxn],d[maxn],ga[maxn];
int sum = 0;
void calc(int idx,int c,int a) {
sum += 1ll * c * a;
g[cnt] += c;ga[cnt] = a;
d[idx] += c;
if(d[idx] == m) unionn(idx - 1,idx);
}
int L[maxn],upd[maxn];
int ans[maxn];
main() {
//freopen("1.in","r",stdin);
n = read(),m = read(),k = read();
for(int aa,s,c,x,i = 1;i <= n;++ i) {
aa = read(),s = read(),c = read(),x = read();
a[++ tot] = node(aa + s,1,0,x ? (c - 1) / x + 1 : maxn - 7);
if(-- c) a[++ tot] = node(aa,c,x,x ? (c - 1) / x + 1 : maxn - 7);
}
int maxd = 0;
for(int i = 1;i <= k;++ i) maxd = std::max(maxd,q[i] = read());
std::sort(a + 1,a + tot + 1);
for(int i = 1;i <= maxd;++ i) fa[i] = i;
for(int i = 1;i <= tot;++ i) {
cnt ++;
int idx = find(std::min(a[i].d,maxd)); //a 价值 d GG日期 d 数量 x 每天GG数
int res = (idx - 1) * a[i].x ,now = a[i].c - res;
while(idx && now) {
int mn = std::min(m - d[idx],now);
calc(idx,mn,a[i].a);
now -= mn;
int p = idx;
idx = find(idx - 1);
p -= idx;
if(res) now += p * a[i].x , res -= p * a[i].x;
}
if(!find(maxd)) break ;
}
int R = 0;
for(int i = 1;i <= maxd;++ i) L[i] = m - d[i] + L[i - 1];
for(int i = maxd;i;-- i) upd[i] = std::max(R - L[i],0ll),R += d[i];
for(int i = maxd;i >= 1;-- i) {
ans[i] = sum;
int tmp = upd[i - 1] - upd[i];
while(tmp) {
int mn = std::min(tmp,g[cnt]);
sum -= 1ll * ga[cnt] * mn;
tmp -= mn;
g[cnt] -= mn;
if(!g[cnt]) -- cnt;
}
}
for(int i = 1;i <= k;++ i) print(ans[q[i]]),pc('\n');// print(10);
return 0;
} // 1110001

bzoj4946: [Noi2017]蔬菜 神烦贪心的更多相关文章

  1. BZOJ4946 NOI2017蔬菜(贪心+堆)

    容易想到一个费用流做法:将每种蔬菜拆成p种,对应p个过期时间,每一种向可以卖的时间连边,第一次卖的奖励算在最晚过期的一种里.对于天数动态加点.不过这样边数太多了,因为第i天能卖的第i-1天一定能卖,可 ...

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

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

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

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

  4. bzoj4946 Noi2017 蔬菜

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

  5. uoj318 [NOI2017]蔬菜 【贪心 + 堆 + 并查集】

    题目链接 uoj 题解 以前看别人博客,在考场上用费用流做,一直以为这题是毒瘤网络流题 没想到竟然是贪心模拟题... 如果只有一个蔬菜呢?这就是一个经典的普及难度的贪心,正着推面临优先选择的困难,而逆 ...

  6. [NOI2017]蔬菜(贪心+递推)

    这题很有思维难度,乍一看基本无从下手. 给每个蔬菜钦定退役的时间显然很困难,可以考虑让时光倒流,从后向前递推,然后就变成了某个时间点有一部分蔬菜服役,而已经服役的蔬菜不会退役了.然后就可以直接考虑贪心 ...

  7. [NOI2017]蔬菜(贪心)

    神仙题啊! 早上开了两个多小时,终于肝出来了,真香 我们考虑从第 \(10^5\) 天开始递推,先生成 \(p=10^5\) 的解,然后逐步推出 \(p-1,...,2,1\) 的解. 那怎么推出 \ ...

  8. [NOI2017]蔬菜 贪心

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

  9. [NOI2017]蔬菜

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

随机推荐

  1. 【vim】按时间回退文本 :earlier 1m

    Vim 会记录文件的更改,你很容易可以回退到之前某个时间.该命令是相当直观的.比如: :earlier 1m 会把文件回退到 1 分钟以前的状态. 注意,你可以使用下面的命令进行相反的转换: :lat ...

  2. java并发编程系列二:原子操作/CAS

    什么是原子操作 不可被中断的一个或者一系列操作 实现原子操作的方式 Java可以通过锁和循环CAS的方式实现原子操作 CAS( Compare And Swap )  为什么要有CAS? Compar ...

  3. angular下载安装

    1.下载安装nodejs 官方地址:https://nodejs.org/en/download/   2.验证是否安装成功 node -v npm -v   公司内网需要设置代理 npm confi ...

  4. spring事物回滚遇到的问题

    在service层使用声明式事务添加@Transactional(rollbackFor = Exception.class)注解 多个方法进行数据库操作,执行失败则隐式的回滚事务,但是已经成功的发方 ...

  5. 09-伪数组 arguments

    arguments代表的是实参.有个讲究的地方是:arguments只在函数中使用. (1)返回函数实参的个数:arguments.length 例子: fn(2,4); fn(2,4,6); fn( ...

  6. 两道SQL题目

    1.查询省内所有城市气温都大于35度的省份(表名:Temp) SELECT province FROM Temp WHERE province NOT IN ( SELECT province FRO ...

  7. 前端开发必须知道的JS之闭包及应用

    本文讲的是函数闭包,不涉及对象闭包(如用with实现).如果你觉得我说的有偏差,欢迎拍砖,欢迎指教. 在前端开发必须知道的JS之原型和继承一文中说过下面写篇闭包,加之最近越来越发现需要加强我的闭包应用 ...

  8. ES6 模块与 CommonJS 模块的差异

    ES6 模块与 CommonJS 模块完全不同.它们有两个重大差异 CommonJS 输出是值的拷贝,即原来模块中的值改变不会影响已经加载的该值,ES6静态分析,动态引用,输出的是值的引用,值改变,引 ...

  9. VS Code 折腾记 - (6) 基本配置/快捷键定义/代码片段的录入(snippet)

    前言 本来分成三篇来写的,但是想了想没必要,大家都是聪明人...简单的东西点一下就晓得了. 基本配置 快捷键自定义(Ctrl+K Ctrl + S) 那个when支持条件表达式返回一个布尔值 支持的快 ...

  10. ngrinder的简介与基本使用(转载:https://www.jianshu.com/p/f336180806cc)

    nGrinder简介 nGrinder是基于Grinder开源项目,由NHN公司的开发团队进行了重新设计和完善.nGrinder是一款非常易用,有简洁友好的用户界面和controller-agent分 ...