(​​http://www.elijahqi.win/2017/12/10/bzoj1221hnoi2001-%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91/%20%E2%80%8E​​​)
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

和餐巾计划几乎一样 就是这次消毒需要a+1,b+1天之后才可以使用
添加入点和出点 出点在上入点在下 出点可以指向出点无限拖延时间
我把每天当作两个点 一个是需要多少 一个是用完多少 我把用完的那个点和源点相连 边权值为r 花费为0 然后用完的这些点还可以不立刻送去洗 留到下一天 或者是 送去快洗 或者是送去慢洗 花费的钱都是题中给定的 然后 还有可能直接购买 就从源点向我需求点 建边权无限 花费为p的边
最后从 需求点向汇点建边 容量为r 价格为0 表示限制住我每天的使用量

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define inf 0x3f3f3f3f
#define N 2200
using namespace std;
inline char gc(){
static char now[1<<16],*S,*T;
if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0;char ch=gc();
while(ch<'0'||ch>'9') ch=gc();
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=gc();}
return x;
}
int num=1,T,h[N],pre[N],path[N],dis[N],fa,fb,f,a,b,n;bool flag[N];
struct node{
int x,y,z,next,c;
}data[N*N];
inline void insert1(int x,int y,int z,int c){
data[++num].y=y;data[num].next=h[x];h[x]=num;data[num].z=z;data[num].c=c;data[num].x=x;
data[++num].y=x;data[num].next=h[y];h[y]=num;data[num].z=0;data[num].c=-c;data[num].x=y;
}
inline bool spfa(){
memset(dis,0x3f,sizeof(dis));memset(flag,0,sizeof(flag));queue<int>q;q.push(0);flag[0]=1;dis[0]=0;memset(pre,-1,sizeof(pre));
while(!q.empty()){
int x=q.front();q.pop();flag[x]=0;
for (int i=h[x];i;i=data[i].next){
int y=data[i].y,z=data[i].z,c=data[i].c;
if(dis[x]+c<dis[y]&&z){
dis[y]=dis[x]+c;pre[y]=x;path[y]=i;
if(!flag[y]) flag[y]=1,q.push(y);
}
}
}if (pre[T]==-1)return 0;else return 1;
}
int main(){
freopen("bzoj1221.in","r",stdin);
n=read();a=read();b=read();f=read();fa=read();fb=read();T=n*2+1;
for (int i=1;i<=n;++i){
int s=read();insert1(0,i,s,0);insert1(i+n,T,s,0);insert1(0,i+n,inf,f);
if(i+a+1<=n) insert1(i,i+a+1+n,inf,fa);if(i+b+1<=n) insert1(i,i+b+1+n,inf,fb);if (i<n) insert1(i,i+1,inf,0);
}int ans=0;
// for (int i=2;i<=num;++i) printf("%d %d %d %d\n",data[i].x,data[i].y,data[i].z,data[i].c);
while(spfa()){
int minn=inf,now=T;
while(now) minn=min(minn,data[path[now]].z),now=pre[now];now=T;
while(now){ans+=minn*data[path[now]].c;data[path[now]].z-=minn;data[path[now]^1].z+=minn;now=pre[now];}
}printf("%d",ans);
return 0;
}