首页 技术 正文
技术 2022年11月16日
0 收藏 524 点赞 3,233 浏览 2097 个字

题目描述

一个餐厅在相继的 NN 天里,每天需用的餐巾数不尽相同。假设第 ii 天需要 r_iri​块餐巾( i=1,2,…,N)。餐厅可以购买新的餐巾,每块餐巾的费用为 pp 分;或者把旧餐巾送到快洗部,洗一块需 m 天,其费用为 f 分;或者送到慢洗部,洗一块需 nn 天(n>mn>m),其费用为 ss 分(s<fs<f)。

每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多少块保存起来延期送洗。但是每天洗好的餐巾和购买的新餐巾数之和,要满足当天的需求量。

试设计一个算法为餐厅合理地安排好 NN 天中餐巾使用计划,使总的花费最小。编程找出一个最佳餐巾使用计划。

我们知道,对于每一天,其实有两种状态:

一天开始状态,这个时候应该决定买多少新的餐巾数目,有没有从洗衣部送过来的东西

第一天结束,我们需要决定,是否需要对用过的餐巾进行封存,是否需要对把衣服送到两种洗衣部里面

那么很明显,一个点不能满足我们的需求,我们可以把点进行拆分,分成白天和晚上,对应有6种情况

我们需要从起点连接每个白天,流量限制,费用为p,代表这个的餐巾选择新购买的数目

从起点再连接每个点的晚上,流量限制为这一天所需的餐巾数目,代表这一天一定会产生这么多的用过的餐巾

从每天早上连接到汇点流量限制为这一天所需的餐巾数目,代表这白天一定会消耗这么多餐巾

由于可以把用过的餐巾存起来,我们把每个晚上的餐巾存到第二天从餐巾,流量为今天用的餐巾数目,费用为0

我们可以把餐巾送到快洗部,那么应该这天晚上的餐巾,送到洗完的那一天的早上,流量上限是INF(因为可能有以前存的衣服),费用为快洗部的费用

也可以把餐巾送到慢洗部,那么应该这天晚上的餐巾,送到洗完的那一天的早上,流量上限是INF(因为可能有以前存的衣服),费用为慢洗部的费用

注意拆点的话,可以把点拆成i和i+n

代码:

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<queue>
#define LL long long
using namespace std;
const LL N = 3e4+,M = 4e6+;
const LL INF = 0x3f3f3f3f;
LL ver[M],edge[M],cost[M],Next[M],head[N];
LL d[N],incf[N],pre[N],v[N],a[N];
LL n,k,tot,s,t,maxflow;
LL ans;
void add(LL x,LL y,LL z,LL c){
ver[++tot]=y,edge[tot]=z,cost[tot]=c;
Next[tot]=head[x],head[x]=tot; ver[++tot]=x,edge[tot]=,cost[tot]=-c;
Next[tot]=head[y],head[y]=tot;
}
bool spfa(){
queue<LL>q;
for (LL i=;i<=N;i++){
d[i]=INF;
}
memset(v,,sizeof(v));
q.push(s);
d[s]=;
v[s]=;
incf[s]=INF;
while(q.size()){
LL x=q.front();
v[x]=;
q.pop();
for (int i=head[x];i;i=Next[i]){
if(!edge[i])
continue;
int y=ver[i];
if (d[y]>d[x]+cost[i] && edge[i]>){
d[y]=d[x]+cost[i];
incf[y]=min(incf[x],edge[i]);
pre[y]=i;
if (!v[y])v[y]=,q.push(y);
}
}
}
if (d[t]==INF)return false;
return true;
}
void update(){
int x=t;
while(x!=s){
int i=pre[x];
edge[i]-=incf[t];
edge[i^]+=incf[t];
x=ver[i^];
}
maxflow+=incf[t];
ans+=d[t]*incf[t];
}
int main(){
LL q_day,q_w,s_day,s_w,p,
maxflow=;
ans=;
tot=;
scanf("%lld",&n);
s=*n+;
t=*n+;
for (LL i=;i<=n;i++){
scanf("%lld",&a[i]);
}
scanf("%lld%lld%lld%lld%lld",&p,&q_day,&q_w,&s_day,&s_w);
for (LL i=;i<=n;i++){
add(s,i,INF,p);
add(s,i+n,a[i],);
add(i,t,a[i],);
if (i<n)add(i+n,i+n+,INF,);
if (i+q_day<=n){
add(i+n,i+q_day,INF,q_w);
}
if (i+s_day<=n){
add(i+n,i+s_day,INF,s_w);
}
}
while(spfa())update();
printf("%lld\n",ans);
return ;
}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,088
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,564
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,413
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,186
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,822
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,905