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的更多相关文章

  1. Mesh Baker的基本操作与功能演示

    原地址:http://www.narkii.com/club/thread-301789-1.html 如何降低游戏在系统中的消耗并带给用户最佳的体验是开发者一直追求的目标,在Unity里面对于模型与 ...

  2. Render To Texel Baker

    今天仔细研究了 Shaowgun 示例中那个金黄色雕像所使用的光照纹理烘焙工具:“Render To Texel Baker”.因为要在移动设备展现比较逼真的光照效果,但是实时使用法线贴图并大量用于场 ...

  3. Lightoj 1071 - Baker Vai (双线程DP)

    题目连接: http://lightoj.com/volume_showproblem.php?problem=1071 题目大意: 一个n*m的格子,Baker Vai要从(1,1)到(n,m)再回 ...

  4. UVa 11308 - Bankrupt Baker

    题目大意:给出一些原料和价钱和若干份菜谱,每份菜谱都标明所需的原料和数量,找出所有不超过预算的菜谱. 没什么好说的,主要是对map的运用. #include <cstdio> #inclu ...

  5. Baker Vai LightOJ - 1071 (MCMF)

    在个给出的矩阵从,从左上角走到右下角,然后再从右下角走到左上角,两次不能经过想同的点,每个点都有一个价值,问最大的价值是多少. 可以把原来的问题化简成从左上角走两条路到右下角,然后把价值加起来,然是这 ...

  6. 混沌数学之Baker模型

    相关DEMO参见:混沌数学之离散点集图形DEMO 相关代码: // http://wenku.baidu.com/view/ac9b57ea172ded630b1cb65b.html class Ba ...

  7. LightOJ 1071 Baker Vai(拆点+最大费用流)题解

    题意:给一个n*m的方格,每个格子上都有一个数字表示价值,小A在左上角,他从左上角走到右下角只能向右或向下走,然后再从右下角走上左上角,这次只能向上或向左走,这两条路绝对没有重复,问你怎样走有最大价值 ...

  8. Baker Vai LightOJ - 1071

    题意:类似传纸条 方法: 把他要求的操作(一个人来回),转化为两个人同时走,除了开始和结束位置只能走不同路,得到的分数和的最大值即可. 一开始想到要定义的状态,是两个人的x(行)和y(列)坐标.这样时 ...

  9. codewars--js--Pete, the baker

    问题描述: Pete likes to bake some cakes. He has some recipes and ingredients. Unfortunately he is not go ...

  10. 开源 iOS 项目分类索引大全 - 待整理

    开源 iOS 项目分类索引大全 GitHub 上大概600个开源 iOS 项目的分类和介绍,对于你挑选和使用开源项目应该有帮助 系统基础库 Category/Util sstoolkit 一套Cate ...

随机推荐

  1. Codeforces-1095E-Almost-Regular-Bracket-Sequence

    题意 给定一个长度为 \(n\) 的小括号序列,求有多少个位置满足将这个位置的括号方向反过来后使得新序列是一个合法的括号序列.即在任意一个位置前缀左括号的个数不少于前缀右括号的个数,同时整个序列左右括 ...

  2. C# MySqlHelp类 "DbModel.MySql"数据库操作类

    以前做易语言/PHP的. 最近刚入门C#, 就简单的封装了一个类库, 边学边玩才容易学到东西嘛, 比起sqlserver, 我还是觉得mysql更加有亲切感; 于是模仿ThinkPHP编写了一个&qu ...

  3. 图解 LeetCode 算法汇总——链表

    本文首发公众号:小码A梦 一般数据主要存储的形式主要有两种,一种是数组,一种是链表.数组是用来存储固定大小的同类型元素,存储在内存中是一片连续的空间.而链表就不同于数组.链表中的元素不是存储在内存中可 ...

  4. 局域网内文件分享的简单方式:python - http.server

    在局域网条件下,利用Python自带的HTTP服务功能提供文件共享服务是相对比较简单便捷的方式之一. 一.现实需求及前提条件 1. 文件的服务端(文件分享者)与接收端(文件接收者)在一个局域网,接收端 ...

  5. MySQL实战实战系列 04 深入浅出索引(上)

    提到数据库索引,我想你并不陌生,在日常工作中会经常接触到.比如某一个 SQL 查询比较慢,分析完原因之后,你可能就会说"给某个字段加个索引吧"之类的解决方案.但到底什么是索引,索引 ...

  6. Python基础——二分法、面向过程编程思想、有名函数、lambda、max、_min的应用、sorted排序、map的应用、filter的应用、reduce的应用

    文章目录 内容回顾 二分法 伪代码模板 面向过程编程思想 函数式 def用于定义有名函数 lambda用于定义匿名函数 调用匿名函数 匿名函数作用 匿名函数的示范 max的应用 min的应用 sort ...

  7. Python经典编程题40题(二)

    Python经典编程题40题(二)    题目 给你一个list L, 如 L=[2,8,3,50], 对L进行降序排序并输出, 如样例L的结果为[50,8,3,2] 输入示例 输入:L = [4, ...

  8. studio

  9. C语言存储类别

    对于C语言中的变量,存储类别可分为4种:auto(自动存储).static(静态存储).register(寄存器存储).extern(外部存储). auto自动存储 函数中的局部变量,如果不专门声明为 ...

  10. Util应用框架 UI 开发快速入门

    本文是Util应用框架 Angular UI 开发快速入门教程. Util前端技术概述 Util 应用框架目前仅支持用于开发管理后台的 UI. 本文介绍了 Util UI 的技术特点和功能支持. UI ...