[ARC137E] Baker
Problem Statement
Snuke runs a bakery.
He is planning for the next $N$ days.
Let us call these days Day $1,2,\cdots,N$.
At the moment, the bakery hires nobody.
There are $M$ bakers that Snuke can hire, numbered $1$ to $M$.
$C_i$ yen must be paid to hire Baker $i$.
If Baker $i$ is hired, they will work on Day $L_i, L_i+1, \cdots, R_i$, baking one loaf of bread each day.
For each $j$ ($1 \leq j \leq N$), there is a limit $A_j$ to the number of loaves of bread that can be sold on Day $j$. If $x_j$ loaves of bread are baked on Day $j$, $\min(x_j, A_j)$ loaves will be sold on that day.
Each loaf of bread sold will yield a profit of $D$ yen.
Snuke wants to choose the set of bakers to hire to maximize the final profit: $($The total number of loaves sold$) \times D - ($The total cost of hiring bakers$)$.
Find the maximum possible value of this.
Constraints
- $1 \leq N \leq 2000$
- $1 \leq M \leq 2000$
- $1 \leq D \leq 10^9$
- $1 \leq A_j \leq M$
- $1 \leq L_i \leq R_i \leq N$
- $1 \leq C_i \leq 10^9$
- All values in input are integers.
网络流中一条流量为 $f$,费用为 $w$ 的边在下文表示为 $(f,w)$
考虑把每天的限制在网络流的边上考虑。
那么 \(i->i+1\) 的点表示这天的情况,连一条 \((a_i,d)\) 的边和一条 \((\infin,0)\) 的边。
然后对于一个面包师,从 \(R_i+1\) 到 \(L_i\) 连一条 \(-C_i\) 的边。
现在就要求他的最大费用循环流就行了。
全部取负,求最小费用循环流。
#include<bits/stdc++.h>
using namespace std;
const int N=2005,T=2004,INF=1e9;
int hd[N],e_num=1,n,m,d,v[N],p[N],g[N],a[N],l[N],r[N],c[N];
priority_queue<pair<long long,int>,vector<pair<long long,int> >,greater<pair<long long,int> > >q;
long long ans,h[N],dis[N];
struct edge{
int u,v,nxt,f,w;
}e[N*10];
void add_edge(int u,int v,int f,int w)
{
e[++e_num]=(edge){u,v,hd[u],f,w};
hd[u]=e_num;
e[++e_num]=(edge){v,u,hd[v],0,-w};
hd[v]=e_num;
}
void spfa()
{
static int l,r,q[N];
memset(h,0x3f,sizeof(h));
v[q[l=r=1]=0]=1,h[0]=0;
while(l<=r)
{
for(int i=hd[q[l%N]];i;i=e[i].nxt)
{
if(e[i].f&&h[e[i].v]>h[q[l%N]]+e[i].w)
{
h[e[i].v]=h[q[l%N]]+e[i].w;
if(!v[e[i].v])
v[q[(++r)%N]=e[i].v]=1;
}
}
v[q[(l++)%N]]=0;
}
}
int dijkstra()
{
memset(dis,0x3f,sizeof(dis));
memset(v,0,sizeof(v));
q.push(make_pair(0,0));
dis[0]=0;
while(!q.empty())
{
int k=q.top().second;
q.pop();
if(v[k])
continue;
v[k]=1;
for(int i=hd[k];i;i=e[i].nxt)
{
if(e[i].f&&dis[k]+e[i].w+h[k]-h[e[i].v]<dis[e[i].v])
{
assert(e[i].w+h[k]-h[e[i].v]>=0);
dis[e[i].v]=dis[k]+e[i].w+h[k]-h[e[i].v];
p[e[i].v]=i;
q.push(make_pair(dis[e[i].v],e[i].v));
}
}
}
return v[T];
}
int main()
{
scanf("%d%d%d",&n,&m,&d);
for(int i=1;i<=n;i++)
scanf("%d",a+i);
for(int i=1;i<=m;i++)
scanf("%d%d%d",l+i,r+i,c+i),g[l[i]]++,g[r[i]+1]--;
for(int i=1;i<=n;i++)
{
g[i]+=g[i-1];
if(g[i]<=a[i])
add_edge(i,i+1,g[i],d);
else
add_edge(i,i+1,a[i],d),add_edge(i,i+1,g[i]-a[i],0);
ans+=min(a[i],g[i])*1LL*d;
}
for(int i=1;i<=m;i++)
{
add_edge(0,l[i],1,0);
add_edge(l[i],r[i]+1,1,c[i]);
add_edge(r[i]+1,T,1,0);
}
spfa();
int ret=0;
while(dijkstra())
{
for(int i=0;i<=n+1;i++)
h[i]=h[i]+dis[i];
h[T]+=dis[T];
int mnf=INF;
for(int i=T;i;i=e[p[i]].u)
mnf=min(mnf,e[p[i]].f);
for(int i=T;i;i=e[p[i]].u)
e[p[i]].f-=mnf,e[p[i]^1].f+=mnf;
ret+=mnf;
ans-=mnf*h[T];
}
printf("%lld",ans);
}
[ARC137E] Baker的更多相关文章
- Mesh Baker的基本操作与功能演示
原地址:http://www.narkii.com/club/thread-301789-1.html 如何降低游戏在系统中的消耗并带给用户最佳的体验是开发者一直追求的目标,在Unity里面对于模型与 ...
- Render To Texel Baker
今天仔细研究了 Shaowgun 示例中那个金黄色雕像所使用的光照纹理烘焙工具:“Render To Texel Baker”.因为要在移动设备展现比较逼真的光照效果,但是实时使用法线贴图并大量用于场 ...
- Lightoj 1071 - Baker Vai (双线程DP)
题目连接: http://lightoj.com/volume_showproblem.php?problem=1071 题目大意: 一个n*m的格子,Baker Vai要从(1,1)到(n,m)再回 ...
- UVa 11308 - Bankrupt Baker
题目大意:给出一些原料和价钱和若干份菜谱,每份菜谱都标明所需的原料和数量,找出所有不超过预算的菜谱. 没什么好说的,主要是对map的运用. #include <cstdio> #inclu ...
- Baker Vai LightOJ - 1071 (MCMF)
在个给出的矩阵从,从左上角走到右下角,然后再从右下角走到左上角,两次不能经过想同的点,每个点都有一个价值,问最大的价值是多少. 可以把原来的问题化简成从左上角走两条路到右下角,然后把价值加起来,然是这 ...
- 混沌数学之Baker模型
相关DEMO参见:混沌数学之离散点集图形DEMO 相关代码: // http://wenku.baidu.com/view/ac9b57ea172ded630b1cb65b.html class Ba ...
- LightOJ 1071 Baker Vai(拆点+最大费用流)题解
题意:给一个n*m的方格,每个格子上都有一个数字表示价值,小A在左上角,他从左上角走到右下角只能向右或向下走,然后再从右下角走上左上角,这次只能向上或向左走,这两条路绝对没有重复,问你怎样走有最大价值 ...
- Baker Vai LightOJ - 1071
题意:类似传纸条 方法: 把他要求的操作(一个人来回),转化为两个人同时走,除了开始和结束位置只能走不同路,得到的分数和的最大值即可. 一开始想到要定义的状态,是两个人的x(行)和y(列)坐标.这样时 ...
- codewars--js--Pete, the baker
问题描述: Pete likes to bake some cakes. He has some recipes and ingredients. Unfortunately he is not go ...
- 开源 iOS 项目分类索引大全 - 待整理
开源 iOS 项目分类索引大全 GitHub 上大概600个开源 iOS 项目的分类和介绍,对于你挑选和使用开源项目应该有帮助 系统基础库 Category/Util sstoolkit 一套Cate ...
随机推荐
- Leetcode刷题笔记——二分法
二分法是搜索算法中极其典型的方法,其要求输入序列有序并可随机访问.算法思想为 输入:有序数组nums,目的数值target 要求输出:如果target存在在数组中,则输出其index,否则输出-1 将 ...
- mac安装nvm
系统:macos catalina版本:10.15.7 一.安装nvm 打开终端执行这个命令 安装的版本是 v0.39.1 curl -o- [https://raw.githubuserconten ...
- LeetCode 周赛上分之旅 #46 经典二分答案与质因数分解
️ 本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 和 BaguTree Pro 知识星球提问. 学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越 ...
- Solution Set -「CF 1520」
「CF 1520A」Do Not Be Distracted! Link. 模拟. #include<bits/stdc++.h> char now; char get_char(){ch ...
- 查看docker容器使用的cpu和内存
转载请注明出处: 使用docker ps命令列出正在运行的Docker容器,并获取目标容器的ID或名称. 使用docker stats <容器ID或名称>命令来实时监测指定容器的资源使用情 ...
- Insert a scratch project into a ppt (MSPowerPoinT file)在powerpoint中播放Scratch动画
Insert a scratch project into a ppt (MSPowerPoinT file)在powerpoint中播放Scratch动画 Contributed by liu pe ...
- .Net核心级的性能优化(GC篇)
1.前言 大部分人对于.Net性能优化,都停留在业务层面.或者简单的.Net框架配置层面.本篇来看下.Net核心部分GC垃圾回收配置:保留VM,大对象,独立GC,节省内存等.Net8里面有很多的各种G ...
- 本地化部署自建类ChatGPT服务远程访问
Text generation web UI可为类ChatGPT的大型语言模型提供能够快速上手的网页界面,不仅可以提高使用效率,还可满足私有化部署,或对模型进行自定义.目前,该Web UI已经支持了许 ...
- C#_TCPClient异步连接和接收消息
//c#不愧是全能型的语言,异步连线程都省了 class State { public byte[] bufferCache; public TcpClient tcpClient; } ... pr ...
- List、Set与 Map
目录 1. List接口和常用方法 1.1 List接口基本介绍 1.2 List接口的三种遍历方式 2. ArrayList 2.1 注意事项 2.2 ArrayList的底层操作机制源码分析(重点 ...