容易想到一个费用流做法:将每种蔬菜拆成p种,对应p个过期时间,每一种向可以卖的时间连边,第一次卖的奖励算在最晚过期的一种里。对于天数动态加点。不过这样边数太多了,因为第i天能卖的第i-1天一定能卖,可以改成每一种只向过期时间连边然后第i天向第i-1天连边。这样就有60分了。但费用流没有什么优化空间了。

  如果蔬菜不会过期的话,贪心做法非常显然。那么,考虑让时光倒流。这样蔬菜只会每天增加,每次贪心的选出价值最大的行了。对于奖励,拆成两种蔬菜就好。

  考虑对于单次询问具体应该怎么做。用一个大根堆维护应该选哪些蔬菜。堆里蔬菜分为两类,一类是每天都能拿的,一类只能拿一次的。每次从堆顶拿出m个蔬菜,如果是每天都能拿的再恢复回去,注意考虑各种情况。

  然后考虑多次询问。我们需要从前p天的答案倒推出前p-1天的答案。注意到第p天能选择的第p-1天一定能选择。并且前p-1天的最优选择应该包含在前p天的最优选择内,否则第p天的选择本来就更少没有理由丢掉之前的较优选择。那么从答案里去掉最小的几个使得剩下的不超过(p-1)m个就可以了。

  感觉写的姿势并不对,于是变的异常难写和丑陋不堪。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 100010
#define inf 1000000000
#define ll long long
int n,m,k,cnt=;
ll tot=,ans[N];
struct data{int v,c,x;
}a[N<<];
struct data2{int i,x;
}Q[N];
struct data3
{
int tim,cnt,val;
bool operator <(const data3&a) const
{
return val<a.val;
}
}choose[N*];
vector<data3> app[N],rec[N];
priority_queue<data3> q;
stack<data3> undo;
bool cmp(const data2&a,const data2&b)
{
return a.x>b.x;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4946.in","r",stdin);
freopen("bzoj4946.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),m=read(),k=read();
for (int i=;i<=n;i++)
a[i].v=read(),a[i+n].v=a[i].v+read(),a[i].c=read()-,a[i+n].c=,a[i].x=read(),a[i+n].x=;
n<<=;
for (int i=;i<=k;i++) Q[i].i=i,Q[i].x=read();
sort(Q+,Q+k+,cmp);
for (int i=;i<=n;i++)
if (a[i].x==)
{
if (i<=(n>>)) app[Q[].x].push_back((data3){,a[i].c,a[i].v});
else app[a[i-(n>>)].x?min(Q[].x,a[i-(n>>)].c/a[i-(n>>)].x+):Q[].x].push_back((data3){,a[i].c,a[i].v});
}
else
{
if (a[i].c-1ll*a[i].x*Q[].x>) app[Q[].x].push_back((data3){,a[i].c-1ll*a[i].x*Q[].x,a[i].v});
else if (a[i].c%a[i].x) app[a[i].c/a[i].x+].push_back((data3){,a[i].c%a[i].x,a[i].v});
rec[min(a[i].c/a[i].x,Q[].x)].push_back((data3){min(a[i].c/a[i].x,Q[].x)+,a[i].x,a[i].v});
}
for (int i=Q[].x;i;i--)
{
for (int j=;j<app[i].size();j++) q.push(app[i][j]);
for (int j=;j<rec[i].size();j++) q.push(rec[i][j]);
int t=m;
while (t&&!q.empty())
{
if (q.top().tim==)
{
if (t>=q.top().cnt) ans[Q[].i]+=1ll*q.top().cnt*q.top().val,t-=q.top().cnt,choose[++cnt]=q.top();
else {ans[Q[].i]+=1ll*t*q.top().val;undo.push((data3){,q.top().cnt-t,q.top().val});choose[++cnt]=(data3){,t,q.top().val};t=;}
}
else
{
int tmp=q.top().cnt*(q.top().tim-i);
if (t>=tmp)
{
ans[Q[].i]+=1ll*tmp*q.top().val;
choose[++cnt]=(data3){,tmp,q.top().val};
undo.push((data3){i,q.top().cnt,q.top().val});
t-=tmp;
}
else
{
ans[Q[].i]+=1ll*t*q.top().val;
if (t>=q.top().cnt) choose[++cnt]=(data3){,q.top().cnt*(t/q.top().cnt),q.top().val};
undo.push((data3){q.top().tim-(t-)/q.top().cnt-,q.top().cnt,q.top().val});
if (t%q.top().cnt) choose[++cnt]=(data3){,t%q.top().cnt,q.top().val},undo.push((data3){,q.top().cnt-t%q.top().cnt,q.top().val});
t=;
}
}
q.pop();
}
while (!undo.empty()) q.push(undo.top()),undo.pop();
}
sort(choose+,choose+cnt+);
int tot=;for (int i=;i<=cnt;i++) tot+=choose[i].cnt;
int t=;long long sum=ans[Q[].i];cnt=;
for (int i=Q[].x-;i;i--)
{
while (tot>i*m)
{
if (tot-i*m>=choose[cnt].cnt) sum-=1ll*choose[cnt].cnt*choose[cnt].val,tot-=choose[cnt++].cnt;
else sum-=1ll*choose[cnt].val*(tot-i*m),choose[cnt].cnt-=tot-i*m,tot=i*m;
}
if (i==Q[t].x) ans[Q[t++].i]=sum;
}
for (int i=;i<=k;i++) printf(LL,ans[i]);
return ;
}

BZOJ4946 NOI2017蔬菜(贪心+堆)的更多相关文章

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

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

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

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

  3. [NOI2017]蔬菜 贪心

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

  4. bzoj4946 Noi2017 蔬菜

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

  5. NOI2017蔬菜(贪心)

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

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

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

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

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

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

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

  9. [NOI2017]蔬菜

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

随机推荐

  1. Tensorflow[目录结构]

    1 - Tensorflow源码目录结构 基于2018年5月28日github的tensorflow源码,即1.8版本 第一层: tensorflow: 核心代码目录. third_party:第三方 ...

  2. TCP/IP协议---ARP协议

    ARP协议 以下就默认在以太网类型的网络. 这个协议的作用是通过ip地址(32bit)找到硬件地址(48bit).顺便提一下:在一个局域网里,大家常见的设备交换机,交换机上的主机在互相通信时,实际用的 ...

  3. 如何下载google play商店里面的app?

    如何不FQ的下载这国际版的app呢? 方法如下: https://androidappsapk.co/category/apps/ 你可以直接登入这个网站,下载你所需要的国际版的软件. 就像是踏入一个 ...

  4. LOJ6089 小Y的背包计数问题 背包、根号分治

    题目传送门 题意:给出$N$表示背包容量,且会给出$N$种物品,第$i$个物品大小为$i$,数量也为$i$,求装满这个背包的方案数,对$23333333$取模.$N \leq 10^5$ $23333 ...

  5. subprocess.Popen指令包含中文导致乱码问题解决

    其实解决起来非常简单,如果了解到Windows中文系统编码为GB2312的话 只需将你包含中文的指令字符串编码为GB2312即可 cmd = u'cd 我的文档' cmd.encode('gb2312 ...

  6. (4)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- Consul服务发现和消费

    上一章说了  Consul服务注册  现在我要连接上Consul里面的服务 请求它们的API接口 应该怎么做呢? 1.找Consul要一台你需要的服务器 1.1 获取Consul下的所有注册的服务 u ...

  7. 使用IdentityServer4实现一个简单的Oauth2客户端模式授权

    1.首先新建一个webAPI项目做为IdentityServer的服务端,提供生成Token的服务,首先修改Startup.cs文件,如下图: 2.增加一个Config.cs文件,以便于提供资源和认证 ...

  8. vue-router 注意事项

    1.vue-router 两种模式 (1)mode:hash,hash模式背后的原理是onhashchange事件,可以在window对象上监听这个事件.vue默认为hash模式 window.onh ...

  9. Scrutiny of Partner's individual project Code

    因为队友的代码并没有完整的实现个人项目的完整功能. 已实现功能: 1.对单个单词进行词频统计 2.能够按照老师的要求的格式对制定的有效字符串进行匹配,并且输出至指定文件. 未实现: 1.对连续多个单词 ...

  10. beta阶段测试基本概况对应机型硬件信息

    机型测试概况 测试结果 测试终端数 品牌分布分析 系统分布分析 分辨率分布 未执行 1 联想 4.0.3 480*800 安装失败 1 联想 4.2.1 480*854 通过 119 华为, 三星, ...