记录编号 240290 评测结果 AAAAAAAAAAAA
题目名称 [网络流24题] 餐巾 最终得分 100
用户昵称 Gravatarstdafx.h 是否通过 通过
代码语言 C++ 运行时间 2.953 s
提交时间 2016-03-22 17:17:05 内存使用 52.88 MiB
显示代码纯文本
#define maxn 5010ul
#define maxe 3000010ul

#include <queue>
#include <stdio.h>
#include <string.h>

struct pii{int x,y;};
struct Edge{int u,v,nx,w,c;};
Edge edge[maxe];
int n,ec=1,headlist[maxn],S,T2,T,cnt,min_cost,A,B,f,fA,fB,tot,dis[maxn],flow[maxn],from[maxn],id[maxn][2],seq[maxn],must[maxn];
bool ex[maxn];
const int inf=0x3fffffff;
std::queue<int> que;

void Add_Edge(int u,int v,int w,int c){
    edge[++ec]=(Edge){u,v,headlist[u],w,c};
    headlist[u]=ec;
    return;
}

void Add(int u,int v,int w,int c){
    Add_Edge(u,v,w,c);
    Add_Edge(v,u,0,-c);
    return;
}

bool spfa(int &cost){
    memset(dis,0x2f,sizeof(dis));
    memset(flow,0,sizeof(flow));
    memset(from,0,sizeof(from));
    memset(ex,0,sizeof(ex));
    que.push(S);flow[S]=inf,dis[S]=0;
    while(!que.empty()){
        int p=que.front();que.pop();ex[p]=false;
        for(int i=headlist[p];i;i=edge[i].nx) if(edge[i].w>0&&dis[edge[i].v]>dis[p]+edge[i].c){
            dis[edge[i].v]=dis[p]+edge[i].c,from[edge[i].v]=i;
            flow[edge[i].v]=std::min(flow[p],edge[i].w);
            if(!ex[edge[i].v]) ex[edge[i].v]=true,que.push(edge[i].v);
        }
    }
    if(dis[T]>(int)(1e8)) return false;
    cost+=flow[T]*dis[T];
    for(int i=T;i;i=edge[from[i]].u) edge[from[i]].w-=flow[T],edge[from[i]^1].w+=flow[T];
    return true;
}

int mcmf(){
    int ans=0;
    while(spfa(ans));
    return ans;
}

bool check(int mid){
	ec=1;
	memset(headlist,0,sizeof(headlist));
	for(int i=1,x;i<=n;i++){
		x=seq[i];
        Add(S,id[i][0],inf,f);
		Add(id[i][0],id[i][1],x,-100000),must[i]=ec-1;
		if(i!=n) Add(id[i][0],id[i+1][0],inf,0);
		if(i+A<=n) Add(id[i][1],id[i+A][0],inf,fA);
		if(i+B<=n) Add(id[i][1],id[i+B][0],inf,fB);
		Add(id[i][1],T2,inf,0);
	}
	Add(T2,T,mid,0);min_cost=mcmf();
	for(int i=1;i<=n;i++) if(edge[must[i]].w!=0) return false;
	return true;
}

int main(){
	freopen("napkin.in","r",stdin);
	freopen("napkin.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&seq[i]),tot+=seq[i];
	scanf("%d%d%d%d%d",&f,&A,&fA,&B,&fB);
	for(int i=1;i<=n;i++) id[i][0]=++cnt,id[i][1]=++cnt;T2=++cnt,T=++cnt;
	int L=0,R=tot,mid,a1,a2,mid2,ans_lower=-1,ans=0x2fffffff;
	while(L<=R){
		mid=(L+R)>>1;
		if(check(mid)) R=mid-1,ans_lower=mid;
		else L=mid+1;
	}
	L=ans_lower,R=tot;
	while(L<=R){
		mid=(L+R)>>1,mid2=(L+mid)>>1;
		check(mid),a1=min_cost;
		check(mid2),a2=min_cost;
		ans=std::min(ans,std::min(a1,a2));
		if(a1>a2) R=mid-1;
		else L=mid2+1;
	}
	if(ans!=-1) printf("%d",ans+tot*100000);
	else printf("%d",tot*f);
	return 0;
}