题目链接

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. K-means聚类算法原理和C++实现

    给定训练集$\{x^{(1)},...,x^{(m)}\}$,想把这些样本分成不同的子集,即聚类,$x^{(i)}\in\mathbb{R^{n}}$,但是这是个无标签数据集,也就是说我们再聚类的时候 ...

  2. NTFS文件系统简介

    原文地址:http://www.cnblogs.com/watertao/archive/2011/11/28/2266595.html 1.简介 NTFS(New Technology File S ...

  3. html的结构-厂子型的布局

    上图所示的布局设计是很常见的.这个该怎么做呢? 技术需求:header 要固定住在顶部,不随鼠标滚动而向上移动:左边的div的有一定的宽度,但是要贴浏览器的底部(屏幕顶部):右边的dv要占据右边的全屏 ...

  4. zabbix系列(七)zabbix3.0添加对tcp连接数及状态的监控

    原理: netstat -an|awk '/^tcp/{++S[$NF]}END{for(a in S) print a,S[a]}' TIME_WAIT 79 ESTABLISHED 6 LISTE ...

  5. kettle的下载、安装和初步使用(windows平台下)(图文详解)

    kettle的下载 žKettle可以在http://kettle.pentaho.org/网站下载                   http://sourceforge.net/projects ...

  6. J 判断二叉树每个结点的权值是否关于根节点完全对称

    如果二叉树每个结点的权值关于根节点完全对称 就输出Yes Sample Input 27 //结点1 2 3 //结点1的左孩子是结点2 右孩子是结点32 4 53 6 74 0 05 0 06 0 ...

  7. python爬取百度贴吧帖子

    最近偶尔学下爬虫,放上第二个demo吧 #-*- coding: utf-8 -*- import urllib import urllib2 import re #处理页面标签类 class Too ...

  8. Linux !的使用

    转自:https://www.linuxidc.com/Linux/2015-05/117774.htm 一.history 78 cd /mnt/ 79 ls 80 cd / 81 history ...

  9. 【noip模拟赛4】Matrix67的派对 dfs

    描述 Matrix67发现身高接近的人似乎更合得来.Matrix67举办的派对共有N(1<=N<=10)个人参加,Matrix67需要把他们安排在圆桌上.Matrix67的安排原则是,圆桌 ...

  10. Redis数据结构之sorted-set

    一:介绍 1.说明 与set的主要区别 sorted-set中的成员需要一个分数,分数可以重复的. 位置是有序的 二:Redis客户端 1.添加 如果key已经存在,再次添加一个key相同的,但是分部 ...