题目描述

某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的 服务,其中一项服务就是要为每个开发人员每天提供一块消毒毛巾,这种消毒毛巾使用一天后必须再做消毒处理后才能使用。消毒方式有两种,A种方式的消毒需要 a天时间,B种方式的消毒需要b天(b>a),A种消毒方式的费用为每块毛巾fA, B种消毒方式的费用为每块毛巾fB,而买一块新毛巾的费用为f(新毛巾是已消毒的,当天可以使用);而且f>fA>fB。公司经理正在规划在 这n天中,每天买多少块新毛巾、每天送多少块毛巾进行A种消毒和每天送多少块毛巾进行B种消毒。当然,公司经理希望费用最低。

你的任务就是:为该软件公司计划每天买多少块毛巾、每天多少块毛巾进行A种消毒和多少毛巾进行B种消毒,使公司在这项n天的软件开发中,提供毛巾服务的总费用最低。

输入输出格式

输入格式:

第1行为n,a,b,f,fA,fB.

第2行为n1,n2,……,nn. (注:1≤f,fA,fB≤60,1≤n≤1000)

输出格式:

最少费用

输入输出样例

输入样例#1:
复制

4  1  2  3  2  1
8 2 1 6
输出样例#1: 复制

38

建立附加源点和汇点S和T


1. 源点到第i天的入点连容量ni费用为0的边


2. 第i天的出点到汇点连容量ni费用为0的边


3. 源点到第i天的出点连容量为INF费用为f的边


4. 第i天的入点到第i+a+1(i+b+1)天的出点连容量为INF费用为fa(fb)的边


5. 第i天的入点到第i+1天的入点连容量为INF费用为0的边

S连出的边表示这一天会剩下ni个脏布,连向T表示这一天要用ni个布

一天用完的ni个布,可以由a(b)方式给第i+a+1(i+b+1)天,也可以不洗,留到下一天再洗

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
struct Node
{
int next,to,c,dis,u;
}edge[];
int num=,head[],inf=2e9,dis[],pre[];
long long ans;
int d[],n,a,b,fa,fb,f;
bool vis[];
void add(int u,int v,int c,int d)
{
num++;
edge[num].next=head[u];
head[u]=num;
edge[num].to=v;
edge[num].dis=d;
edge[num].c=c;
edge[num].u=u;
num++;
edge[num].next=head[v];
head[v]=num;
edge[num].to=u;
edge[num].dis=-d;
edge[num].c=;
edge[num].u=v;
}
bool SPFA()
{int INF,i;
memset(pre,-,sizeof(pre));
memset(vis,,sizeof(vis));
memset(dis,/,sizeof(dis));
INF=dis[];
dis[]=;
queue<int>Q;
Q.push();
while (Q.empty()==)
{
int u=Q.front();
Q.pop();
vis[u]=;
for (i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
if (edge[i].c&&dis[v]>dis[u]+edge[i].dis)
{
dis[v]=dis[u]+edge[i].dis;
pre[v]=i;
if (vis[v]==)
{
vis[v]=;
Q.push(v);
}
}
}
}
if (dis[*n+]==INF) return ;
return ;
}
void change()
{int i;
int T=*n+;
int minf=inf;
for (i=pre[T];i!=-;i=pre[edge[i].u])
{
minf=min(minf,edge[i].c);
}
for (i=pre[T];i!=-;i=pre[edge[i].u])
{
edge[i].c-=minf;
edge[i^].c+=minf;
}
ans+=minf*dis[T];
}
int main()
{int i;
cin>>n>>a>>b>>f>>fa>>fb;
for (i=;i<=n;i++)
scanf("%d",&d[i]);
for (i=;i<=n;i++)
add(,i,d[i],),add(i+n,*n+,d[i],),add(,i+n,inf,f);
for (i=;i<=n-;i++)
add(i,i+,inf,);
for (i=;i<=n;i++)
{
if (i+a+<=n) add(i,i+a++n,inf,fa);
if (i+b+<=n) add(i,i+b++n,inf,fb);
}
while (SPFA()) change();
cout<<ans;
}

最新文章

  1. 移动web开发调试工具AlloyLever介绍
  2. jwplayer播放器停止 单页内多个jwplayer对象停止问题
  3. str_replace vs preg_replace
  4. 第12周&amp;第13周
  5. postgresql9.5 run 文件linux安装后配置成开机服务
  6. hdu 2190
  7. sendrose【SPFA】
  8. github的SSH配置如下
  9. python列表反转
  10. 自学Zabbix2.6-zabbix升级
  11. ASP.NET CORE中使用Cookie身份认证
  12. 【webstorm使用手册】如何让webstorm支持nextcss基础语法?
  13. 苹果新的编程语言 Swift 语言进阶(十六)--泛型
  14. github提交代码contributions不显示小绿块
  15. SQL SERVER 一个SQL语句的执行顺序
  16. Deep learning with Python 学习笔记(4)
  17. HTML5学习笔记(二十四):DOM扩展
  18. 利用Everything开启http服务测试移动端浏览器环境
  19. acedSSGet 翻译
  20. C++学习笔记1(Windows程序运行原理及程序编写流程)

热门文章

  1. C语言第三周作业---单层循环
  2. 雷云Razer Synapse2.0使用测评 -第二次作业
  3. 使用 memoryview 和 struct 查看一个 GIF 图像的首部
  4. Android Studio使用过程中遇到的错误
  5. UWP 页面间传递参数(常见类型string、int以及自定义类型)
  6. MySQL InnoDB锁机制
  7. 更优雅的方式: JavaScript 中顺序执行异步函数
  8. 【转】optach学习
  9. cookieUtil
  10. GIT入门笔记(17)- 创建分支dev_lsq, 提交到代码