bzoj 1221: [HNOI2001] 软件开发

1221: [HNOI2001] 软件开发

Time Limit: 10 Sec   Memory Limit: 162 MB
Submit: 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 1
8 2 1 6

Sample Output

38

HINT

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[N],point[N],v[N],c[N],remain[N],d[N];
int dis[N],can[N],laste[N];
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);
}



你可能感兴趣的:(bzoj 1221: [HNOI2001] 软件开发)