刷了n次用了奇淫技巧才拿到rk1,亥

这道题是网络流二十四题中「餐巾计划问题」的加强版。

于是怀着试一试的心情用费用流交了一发:

哇塞,过了9个点!(强烈谴责出题人用*造数据

下面是费用流解法简述:

那么我们把每一天拆为早上和晚上两个点,设为 \(day_i,night_i\) 。

首先可以人为地规定一点:对一块餐巾,我们要么在其脏了之后立即送洗,要么买一块新干净餐巾来代替它。

然后对于每一个操作,我们可以如下连边:

对于买新干净餐巾:我们可以视作从源点买餐巾,从 \(s\) 向 \(day_i\) 连边即可

对于送慢洗部:从 \(night_i\) 向 \(day_{i+n}\) 连边,流量为 \(inf\) ,费用为 \(f\)。

对于送快洗部:从 \(night_i\) 向 \(day_{i+m}\) 连边,流量为 \(inf\) ,费用为 \(s\)。

但是我们注意到,可能存在某一天的干净餐巾冗余。

于是我们要从 \(day_i\) 向 \(day_{i+1}\) 连一条费用为零,流量为 \(inf\) 的单向边。

如何保证每天刚好只用 \(r_i\) 块餐巾?

将其拆成两个板块:

从 \(day_i\) 向 \(t\) 连边,流量为 \(r_i\),费用为 \(0\)。

从 \(s\) 向 \(night_i\) 连边,流量为 \(r_i\),费用为 \(0\)。


优化无果,于是猜想可以不用费用流。

首先无论餐巾是最开始一起买还是需要用时再买,不会影响最终的答案。

那么如果我们已经确定了要买的新餐巾的张数,那么是否可以确定一种唯一的方案使得总花费最小呢?

不难得到有这样一种贪心策略:

在能够用新餐巾的时候,尽量使用新餐巾。

设 \(m\) 为慢洗的天数。

如果无新餐巾可用,则倒回到 \(m\) 天前,找用过的旧餐巾进行慢洗。

如果没有 \(m\) 天以前的旧餐巾可用,则由时间线从近到远地找旧餐巾进行快洗。

这样做使得时间线较远的旧餐巾更有可能慢洗。

如果慢洗比快洗贵,那么直接将慢洗的时间和价格都改为快洗的时间和价格即可。

朴素代码无O2只能过掉70分。

于是我怀疑单次判断的时间复杂度过高。有的题解里说是 \(O(n)\) 的,但我死活没看出来。

于是我们可以优化常数。

注意到在如果在第 \(i\) 天需要慢洗,所有在第 \(i-m\) 天前的旧餐巾对于我们来说是等效的,因为我们显然没有办法将其拿去快洗。

所以我们每次将第 \(i-m\) 天前的旧餐巾全部累加至第 \(i-m\) 天即可。这样可以优化一定的常数。

这样可以保证在计算慢洗的时候一定是线性的,但仍然不能保证计算快洗部分时为线性。

最后我们需要确定最优解时需购买餐巾的张数 \(c\)。

设最优解时最小代价为 \(f(c)\),设当前枚举到了 \(x\)。

则当 $x \ge c $,一定有 \(f(x) \ge f(c)\),因为你还需要多出钱买新餐巾。

当 \(x \le c\),则要么不存在 \(f(x)\) ,即购买 \(x\) 张餐巾不能达到目的,要么此时多洗一张餐巾一定劣于多买一张餐巾,也有 \(f(x) \ge f(c)\)。

所以对于最优解 \(c\) 我们可以三分求解。

个人认为代码可读性还是挺高的,可以康康代码:

/*---Author:HenryHuang---*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=5e5+5;
const ll inf=1ll<<50;
ll sumr=0;
ll r[maxn],res[maxn];
ll n,m1,m2,c1,c2,p;
ll f(ll num){
ll ans=1ll*num*p;//提前算好新餐巾代价
ll now=0;
for(ll i=1;i<=n;++i){
res[i]=0;
if(r[i]){
ll tmp=r[i];
if(num){
ll k=min(tmp,num);
tmp-=k,res[i]+=k,num-=k;
if(!tmp) continue;
}//直接用新的
for(ll j=now;j<i-m2;++j){
res[j+1]+=res[j],res[j]=0;
}//累加旧洗餐巾
now=max(now,i-m2);
if(now<i&&res[now]){
ll k=min(tmp,res[now]);
res[now]-=k,res[i]+=k;
tmp-=k,ans+=1ll*k*c2;
if(!tmp) continue;
}//慢洗
for(ll j=i-m1;j>=1&&j>i-m2;--j){
if(res[j]){
ll k=min(tmp,res[j]);
res[j]-=k,res[i]+=k;
tmp-=k,ans+=1ll*k*c1;
}
if(!tmp) break;
}//快洗
if(tmp) return inf;
}
}
return ans;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>m1>>m2>>c1>>c2>>p;
if(m1>m2) swap(m1,m2),swap(c1,c2);//1快2慢
if(c1<c2) c2=c1,m2=m1;
for(ll i=1;i<=n;++i)
cin>>r[i],sumr+=r[i];
ll l=1,r=max(10000ll,sumr/3);//奇淫技巧
ll ans=inf;
while(r-l>2){
ll k=(r-l)/3;
ll mid1=l+k,mid2=r-k;
ll aa=f(mid1),bb=f(mid2);
if(aa<bb) ans=min(ans,aa),r=mid2;
else ans=min(ans,bb),l=mid1;
}
for(ll i=l;i<=r;++i) ans=min(ans,f(i));
cout<<ans<<'\n';
return 0;
}

P4480 「BJWC2018」「网络流与线性规划24题」餐巾计划问题的更多相关文章

  1. 网络流24题 P1251 餐巾计划问题 拆点

    题目描述 一个餐厅在相继的 NN 天里,每天需用的餐巾数不尽相同.假设第 ii 天需要 r_iri​块餐巾( i=1,2,...,N).餐厅可以购买新的餐巾,每块餐巾的费用为 pp 分;或者把旧餐巾送 ...

  2. LOJ6003 - 「网络流 24 题」魔术球

    原题链接 Description 假设有根柱子,现要按下述规则在这根柱子中依次放入编号为的球. 每次只能在某根柱子的最上面放球. 在同一根柱子中,任何2个相邻球的编号之和为完全平方数. 试设计一个算法 ...

  3. LOJ6002 - 「网络流 24 题」最小路径覆盖

    原题链接 Description 求一个DAG的最小路径覆盖,并输出一种方案. Solution 模板题啦~ Code //「网络流 24 题」最小路径覆盖 #include <cstdio&g ...

  4. LOJ6001 - 「网络流 24 题」太空飞行计划

    原题链接 Description 有个实验和个仪器,做实验有报酬买仪器有花费.每个实验都需要一些仪器,求最大净收益(实验报酬仪器花费),并输出一组方案. Solution 实验向所需仪器连边,实验的点 ...

  5. LOJ6000 - 「网络流 24 题」搭配飞行员

    原题链接 题意简述 求二分图的最大匹配. 题解 这里写的是匈牙利算法. 表示节点的当前匹配. 为真表示在这一轮匹配中,无法给节点一个新的匹配.所以如果为真就不用再dfs它了,直接continue就好. ...

  6. LibreOJ #6014. 「网络流 24 题」最长 k 可重区间集

    #6014. 「网络流 24 题」最长 k 可重区间集 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   ...

  7. Libre 6013 「网络流 24 题」负载平衡 (网络流,最小费用最大流)

    Libre 6013 「网络流 24 题」负载平衡 (网络流,最小费用最大流) Description G 公司有n 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使n ...

  8. Libre 6012 「网络流 24 题」分配问题 (网络流,费用流)

    Libre 6012 「网络流 24 题」分配问题 (网络流,费用流) Description 有n件工作要分配给n个人做.第i个人做第j件工作产生的效益为\(c_{ij}\).试设计一个将n件工作分 ...

  9. Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流)

    Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流) Description W 公司有m个仓库和n个零售商店.第i个仓库有\(a_i\)个单位的货物:第j个零售商店需要\( ...

随机推荐

  1. MyBatis-框架使用和分析

      一.基础知识 MyBatis 是一款优秀的持久层框架,它支持自定义 SQL.存储过程以及高级映射.MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作.MyBatis 可 ...

  2. Tomcat 中文乱码

    问题描述 tomcat9启动后会有中文乱码,比如控制台乱码: startup.bat启动时乱码: 解决方法 打开"/apache-tomcat-9.0.20/conf/logging.pro ...

  3. 调试动态加载的js

    用浏览器无法调试异步加载页面里包含的js文件.简单的说就是在调试工具里面看不到异步加载页面里包含的js文件   最近在一个新的web项目中开发功能.这个项目的管理界面有一个特点,框架是固定的,不会刷新 ...

  4. Python_Selenium之basepage 识别元素、浏览器操作、获取属性、鼠标事件、键盘事件、弹窗、切换frame、切换句柄等封装

    #coding=gbkimport osimport timefrom selenium import webdriverfrom selenium.webdriver.common.by impor ...

  5. fiddler选项卡-Filters(过滤)

    Filter filter的意思是过滤,在fiddler中,它可以用来过滤请求,使得session列表能够更加精准的展现抓到的数据流,而不是杂乱的一堆. 1.filter的界面 2.界面详解 1.Us ...

  6. P1024 [NOIP2001 提高组] 一元三次方程求解

    题目描述 有形如:a x^3 + b x^2 + c x + d = 0 这样的一个一元三次方程.给出该方程中各项的系数(a,b,c,d均为实数),并约定该方程存在三个不同实根(根的范围在 -100至 ...

  7. 大厂面试必问!HashMap 怎样解决hash冲突?

    HashMap冲突解决方法比较考验一个开发者解决问题的能力. 下文给出HashMap冲突的解决方法以及原理分析,无论是在面试问答或者实际使用中,应该都会有所帮助. 在Java编程语言中,最基本的结构就 ...

  8. 身为一枚优秀的程序员必备的基于Redis的分布式锁和Redlock算法

    1 前言 今天开始来和大家一起学习一下Redis实际应用篇,会写几个Redis的常见应用. 在我看来Redis最为典型的应用就是作为分布式缓存系统,其他的一些应用本质上并不是杀手锏功能,是基于Redi ...

  9. Java源码详解系列(十二)--Eureka的使用和源码

    eureka 是由 Netflix 团队开发的针对中间层服务的负载均衡器,在微服务项目中被广泛使用.相比 SLB.ALB 等负载均衡器,eureka 的服务注册是无状态的,扩展起来非常方便. 在这个系 ...

  10. xshell连接时报错:Could not connect to '192.168.2.125' (port 22): Connection failed.

    解决思路: 1.首先用主机ping下虚拟机IP,看是否能ping通 2.如果ping不通就看虚拟机防火墙是否开启,service iptables status [root@mysql ~]# ser ...