bzoj 1221: [HNOI2001] 软件开发
2016-04-05 14:26
405 查看
1221: [HNOI2001] 软件开发
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1166 Solved: 642
[Submit][Status][Discuss]
Description
某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员每天提供一块消毒毛巾,这种消毒毛巾使用一天后必须再做消毒处理后才能使用。消毒方式有两种,A种方式的消毒需要a天时间,B种方式的消毒需要b天(b>a),A种消毒方式的费用为每块毛巾fA, B种消毒方式的费用为每块毛巾fB,而买一块新毛巾的费用为f(新毛巾是已消毒的,当天可以使用);而且f>fA>fB。公司经理正在规划在这n天中,每天买多少块新毛巾、每天送多少块毛巾进行A种消毒和每天送多少块毛巾进行B种消毒。当然,公司经理希望费用最低。你的任务就是:为该软件公司计划每天买多少块毛巾、每天多少块毛巾进行A种消毒和多少毛巾进行B种消毒,使公司在这项n天的软件开发中,提供毛巾服务的总费用最低。Input
第1行为n,a,b,f,fA,fB. 第2行为n1,n2,……,nn. (注:1≤f,fA,fB≤60,1≤n≤1000)Output
最少费用Sample Input
4 1 2 3 2 18 2 1 6
Sample Output
38HINT
Source
题解:与网络流24题的餐巾计划问题几乎一样,但是需要注意消毒毛巾需要A天,那么真正用上是在a+1天#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define N 100000 using namespace std; int n,m,fa,fb,f,a,b,tot=-1,minn,flow; int next ,point ,v ,c ,remain ,d ; int dis ,can ,laste ; const int inf=1e9; void add(int x,int y,int z,int k) { tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y; c[tot]=k; remain[tot]=z; tot++; next[tot]=point[y]; point[y]=tot; v[tot]=x; c[tot]=-k; remain[tot]=0; } int addflow(int s,int t) { int now=t; int ans=inf; while (now!=s) { ans=min(ans,remain[laste[now]]); now=v[laste[now]^1]; } now=t; while (now!=s) { remain[laste[now]]-=ans; remain[laste[now]^1]+=ans; now=v[laste[now]^1]; } return ans; } bool spfa(int s,int t) { memset(dis,0x7f,sizeof(dis)); dis[s]=0; can[s]=1; queue<int> p; p.push(s); while (!p.empty()) { int now=p.front(); p.pop(); for (int i=point[now];i!=-1;i=next[i]) if (dis[v[i]]>dis[now]+c[i]&&remain[i]) { dis[v[i]]=dis[now]+c[i]; laste[v[i]]=i; if (can[v[i]]==0) { can[v[i]]=1; p.push(v[i]); } } can[now]=0; } if (dis[t]>inf) return false; int k=addflow(s,t); flow+=k; minn+=k*dis[t]; return true; } void maxflow(int s,int t) { while (spfa(s,t)); } int main() { memset(next,-1,sizeof(next)); memset(point,-1,sizeof(point)); scanf("%d%d%d%d%d%d",&n,&a,&b,&f,&fa,&fb); for (int i=1;i<=n;i++) scanf("%d",&d[i]); for (int i=1;i<=n;i++) add(0,i,d[i],0),add(0,i+n,inf,f); for (int i=1;i<=n;i++) { if (i+a+1<=n) add(i,i+a+n+1,inf,fa); if (i+b+1<=n) add(i,i+b+n+1,inf,fb); add(i+n,2*n+1,d[i],0); if (i+1<=n) add(i,i+1,inf,0); } maxflow(0,2*n+1); printf("%d\n",minn); }
相关文章推荐
- codeforces 651C Watchmen
- Hdu 5052 Yaoge’s maximum profit(树链剖分)
- 技能要求备注
- STL set容器添加结构体并排序
- win7系统如何删除注册表里面的垃圾文件?
- ios UI控件的简单整理
- 详解Ruby中正则表达式对字符串的匹配和替换操作
- Android AsyncTask源码分析
- Linux find的用法
- Protobuf 入门
- RecycleView添加头部尾部原理笔记
- <text/>
- Mybatis整合spring的时候用log4j输出sql信息的debug设置
- activiti5用户任务分配
- 负载均衡层次结构:LVS Nginx DNS CDN
- IDL读取netcdf数据(.nc)
- 快速WCF
- c++复习:C++的精髓—虚函数virtual用法白话详解
- 修改tomcat命令窗口名称
- 编译FaceAlignment