bzoj4946 Noi2017 蔬菜
题目描述
小 N 是蔬菜仓库的管理员,负责设计蔬菜的销售方案。
在蔬菜仓库中,共存放有nn 种蔬菜,小NN 需要根据不同蔬菜的特性,综合考虑各方面因素,设计合理的销售方案,以获得最多的收益。
在计算销售蔬菜的收益时,每销售一个单位第ii 种蔬菜,就可以获得a_iai 的收益。
特别地,由于政策鼓励商家进行多样化销售,第一次销售第 i 种蔬菜时,还会额外得到s_isi 的额外收益。
在经营开始时,第ii 种蔬菜的库存为c_ici 个单位。
然而,蔬菜的保鲜时间非常有限,一旦变质就不能进行销售,不过聪明的小 N 已经计算出了每个单位蔬菜变质的时间:对于第ii 种蔬菜,存在保鲜值x_ixi ,每天结束时会有x_ixi 个单位的蔬菜变质,直到所有蔬菜都变质。(注意:每一单位蔬菜的变质时间是固定的,不随销售发生变化)
形式化地:对于所有的满足条件d \times x_i \leqslant cid×xi⩽ci 的正整数dd ,有x_ixi 个单位的蔬菜将在第dd 天结束时变质。
特别地,若(d - 1) \times x_i \leqslant c_i \leqslant d \times x_i(d−1)×xi⩽ci⩽d×xi ,则有c_i - (d - 1) \times x_ici−(d−1)×xi 单位的蔬菜将在第dd 天结束时变质。
注意,当x_i = 0xi=0 时,意味着这种蔬菜不会变质。
同时,每天销售的蔬菜总量也是有限的,最多不能超过mm 个单位。
现在,小 N 有kk 个问题,想请你帮忙算一算。每个问题的形式都是:对于已知的p_jpj ,如果需要销售p_jpj 天,最多能获得多少收益?
输入输出格式
输入格式:
第一行包含三个正整数n, m, kn,m,k ,分别表示蔬菜的种类数目、每天能售出蔬菜总量上限、小 N 提出的问题的个数。
接下来nn 行,每行输入四个非负整数,描述一种蔬菜的特点,依次为a_i, s_i, c_i, x_iai,si,ci,xi ,意义如上文所述。
接下来kk 行,每行输入一个非负整数p_jpj ,意义如上文所述。
输出格式:
输出kk 行,每行包含一个整数,第ii 行的数表示第ii 个问题的答案。
题意:
定义了一种蔬菜为:ai,si,ci,xi;
意思是蔬菜的价格为ai,第一份卖出时价格为ai+si,一共有ci份,每天会有xi份过期;每天最多卖出m份蔬菜,多组输入天数依次最大化收入;
题解:
①一个很神的贪心:我们尽量晚点卖过期晚的,早点卖贵的;
②现在想象有一个天数的序列,我们狡猾而又贪心地往里面填蔬菜。为了处理第一次卖出,我们把一种蔬菜分成两种,(1,ai+si)和(ci-1,ai),第一份蔬菜最后过期。把所有蔬菜里最贵的先拿出来,找到当前蔬菜最后过期的那一天,尽量把那一天放满,满了之后再往前面找,后面过期的在前一天一定可以放,动态加上比较早过期的一直放直到放不下或放完。
③本来能放的最后一天(可以(ci-1)/xi+1)o(1)算,并查集维护一下往前没满的第一个位置可以保证复杂度。注意特判一下 xi==0永不过期;
⑤要求多组询问,考虑d天内卖掉的蔬菜为S,我们d-1天一定是丢掉比较便宜的蔬菜,丢掉的个数即为d天选的蔬菜减前面空着的总份数,求出最后一天的状态往前减即可。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N = ;
int n,m,k,f[N],d[N],ga[N],g[N],cnt,tot,Q[N],maxd,upd[N];
ll ans[N],sum,L[N],R;
struct node {int c,a,x,d;}A[N];
char gc(){
static char *p1,*p2,s[];
if(p1==p2) p2=(p1=s)+fread(s,,,stdin);
return (p1==p2)?EOF:*p1++;
}
int rd(){
int x = ; char c = gc();
while(c<''||c>'') c = gc();
while(c>=''&&c<='') x = x * + c - '',c = gc();
return x;
}
bool cmp(const node &x,const node &y){return x.a > y.a;}
int find(int x){return(f[x]==x)?x:f[x]=find(f[x]);}
void Union(int x,int y){int fx = find(x),fy = find(y);if(fx==fy)return;f[fy] = fx;}
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) Union(idx-,idx);
}
int main()
{ //freopen("mzoj1115.in","r",stdin);
//freopen("mzoj1115.out","w",stdout);
freopen("testdata.in","r",stdin);
freopen("testdata.out","w",stdout);
n = rd(); m = rd(); k = rd();
for(int i = ,a,s,c,x;i <= n;i++){
a=rd(),s=rd(),c=rd(),x=rd();
A[++tot] = (node){,a+s,,x?(c-)/x+:N};
if(--c) A[++tot] = (node){c,a,x,x?(c-)/x+:N};
}
for(int i = ,x;i <= k;i++) {
maxd = max(maxd,Q[i] = rd());
}
sort(A+,A+tot+,cmp);
for(int i = ;i <= maxd;i++) f[i] = i;
for(int i = ;i <= tot;i++) {
cnt++;
int idx=find(min(A[i].d,maxd));
int res = (idx-)*A[i].x,now = A[i].c - res;
while(idx&&now){
int tmp = m - d[idx];
int mn = min(tmp,now);
calc(idx,mn,A[i].a);
now -= mn;
int p = idx; idx = find(idx - ); p-=idx;
if(res) now += p*A[i].x,res -= p*A[i].x;
}
if(!find(maxd)) break;
}
//for(int i = 1;i <= cnt/2;i++) swap(g[i],g[cnt-i+1]),swap(ga[i],ga[cnt-i+1]);
for(int i = ;i <= maxd;i++) L[i] = m - d[i] + L[i - ];
for(int i = maxd;i >= ;i--)
upd[i] = max(R - L[i],0ll),R+=d[i];
for(int i = maxd;i>=;i--){
ans[i] = sum;
int tmp = upd[i-] - upd[i];
while(tmp){
int mn = min(tmp,g[cnt]);
sum -= 1ll * ga[cnt] * mn;
tmp -= mn; g[cnt] -= mn; if(!g[cnt]) cnt--;
}
}
for(int i = ;i <= k;i++) printf("%lld\n",ans[Q[i]]);
return ;
}//by tkys_Austin;
bzoj4946 Noi2017 蔬菜的更多相关文章
- bzoj4946: [Noi2017]蔬菜 神烦贪心
题目链接 bzoj4946: [Noi2017]蔬菜 题解 挺神的贪心 把第次买的蔬菜拆出来,记下每种蔬菜到期的日期,填第一单位蔬菜比其他的要晚 按价格排序后,贪心的往前面可以填的位置填就可以了.找可 ...
- BZOJ4946[Noi2017]蔬菜——线段树+堆+模拟费用流
题目链接: [Noi2017]蔬菜 题目大意:有$n$种蔬菜,每种蔬菜有$c_{i}$个,每种蔬菜每天有$x_{i}$个单位会坏掉(准确来说每天每种蔬菜坏掉的量是$x_{i}-$当天这种蔬菜卖出量), ...
- BZOJ4946 NOI2017蔬菜(贪心+堆)
容易想到一个费用流做法:将每种蔬菜拆成p种,对应p个过期时间,每一种向可以卖的时间连边,第一次卖的奖励算在最晚过期的一种里.对于天数动态加点.不过这样边数太多了,因为第i天能卖的第i-1天一定能卖,可 ...
- 【BZOJ4946】[NOI2017]蔬菜(贪心)
[BZOJ4946][NOI2017]蔬菜(贪心) 题面 BZOJ 洛谷 UOJ 题解 忽然发现今年\(NOI\)之前的时候切往年\(NOI\)的题目,就\(2017\)年的根本不知道怎么下手(一定是 ...
- [NOI2017]蔬菜
[NOI2017]蔬菜 题目描述 大意就是有\(n\)种物品,第\(i\)个物品有\(c_i\)个,单价是\(a_i\).然后每天你可以卖出最多\(m\)个物品.每天结束后第\(i\)种物品会减少\( ...
- 4946: [Noi2017]蔬菜
4946: [Noi2017]蔬菜 http://www.lydsy.com/JudgeOnline/upload/Noi2017D2.pdf 分析: 贪心. 首先可以将一个蔬菜拆成两个,一个是有加成 ...
- [NOI2017]蔬菜 贪心
题面: [NOI2017]蔬菜 题解: 首先每天蔬菜会变质这点并不好处理,我们考虑让时间倒流,从后向前处理,这样的话就相当于每天都会得到一定量的蔬菜. 这样做有什么好处呢? 我们可以发现一个性质:如果 ...
- BZOJ4946 & 洛谷3826 & UOJ318:[NOI2017]蔬菜——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4946 https://www.luogu.org/problemnew/show/P3826 ht ...
- NOI2017蔬菜(贪心)
小 N 是蔬菜仓库的管理员,负责设计蔬菜的销售方案. 在蔬菜仓库中,共存放有 n 种蔬菜,小 N 需要根据不同蔬菜的特性,综合考虑各 方面因素,设计合理的销售方案,以获得最多的收益. 在计算销售蔬菜的 ...
随机推荐
- exports
暴露函数 var bar = require("./bar.js"); var msg = "你好"; var info = "呵呵"; f ...
- 理解Python迭代对象、迭代器、生成器
作者:zhijun liu链接:https://zhuanlan.zhihu.com/p/24376869来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 本文源自RQ作 ...
- ios中录音功能的实现AudioSession的使用
这个星期我完成了一个具有基本录音和回放的功能,一开始也不知道从何入手,也查找了很多相关的资料.与此同时,我也学会了很多关于音频方面的东西,这也对后面的录音配置有一定的帮助.其中参照了<iPhon ...
- 201421123042 《Java程序设计》第12周
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 面向系统综合设计-图书馆管理系统或购物车 使用流与文件改造你的图书馆管理系统或购物车. 2.1 简述如何 ...
- JAVA_SE基础——60.初识Object
java是面向对象的语言,核心思想:找适合 的对象做适合 的事情:方式一:自定义类,然后通过自定义的类创建对象.方式二:sun提供了很多的类给我使用,我们只需要认识这些类,我们就可以通过这些类创建对象 ...
- Code::Blocks出现64-Bit mode not compled in解决方法
原因是:Settings->compilter你选了Target x86 _64(64bit),选择Target x86 _32(32bit)即可 废了老半天劲才找到原因,希望能让朋友们少走弯路
- AngularJS1.X学习笔记13-路由
ThinkPHP框架有路由的概念,看起来路由更多的是后端的事情,Angular怎么也会跑出个路由呢?事实上,Angular是着眼于单页应用的,他的一个应用一般来说是一个页面,你所看到的页面内容的改变, ...
- maven入门(1-3)maven的生命周期
maven的生命周期 maven的生命周期是抽象的,其实际行为都由插件来完成,引入maven 的 生命周期就是为了对所有的构建过程进行抽象和统一. 这种方式类似于模板方法,模板方法模式在父类中定义 ...
- Linux将端口设置进防火墙的白名单
1.先检查linux服务器的端口是否被防火墙拦住 `telnet 172.168.1.101 8080后面跟端口号,如果连接上证明是防火墙白名单.如果没有配置 vi /etc/sysconfig/ip ...
- PHP环境配置(1)
Apache下载 Apache下载地址:http://httpd.apache.org/download.cgi 第一步:点击Files for Microsoft Windows 第二步:点击Apa ...