【题解】餐巾计划问题
【题解】餐巾计划问题
orz argent
一定要注意不要调到题目里的坑里来了,要记得脱离实际(大雾)。
建模方法:我觉得没什么好讲的,真的是灵感问题,此外,这个问题可以直接无源汇上下界网络流。但是我不会
graph LR
净1 --w=r,c=0--> T
净2 --w=r,c=0--> T
净3 --w=r,c=0--> T
净4 --w=r,c=0--> T
S --w=r,c=p--> 净1
S --w=r,c=p--> 净2
S --w=r,c=p--> 净3
S --w=r,c=p--> 净4
脏1--w=r,c=0--> 脏2
脏2--w=r,c=0--> 脏3
脏3--w=r,c=0--> 脏4
S --w=r,c=0--> 脏1
S --w=r,c=0--> 脏2
S --w=r,c=0--> 脏3
S --w=r,c=0--> 脏4
脏1 --w=inf,c=s or m --> 净2
脏1 --w=inf,c=s or m --> 净2
保证净到\(T\)一定满流即可。
//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std; typedef long long ll;
inline int qr(){
register int ret=0,f=0;
register char c=getchar();
while(c<48||c>57)f|=c==45,c=getchar();
while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
typedef const int& cont;
const int maxn=4e3+5;
struct E{
int to,w,c,nx;
E(){to=c=w=nx=0;}
E(cont a,cont b,cont C,cont d){to=a;w=b;c=C;nx=d;}
}e[maxn<<4|1];
int head[maxn];
int cnt=1;
int T,S;
const int inf=0x3f3f3f3f;
queue< int > q;
inline void add(cont fr,cont to,cont w,cont c,cont f=1){
e[++cnt]=E(to,w,c,head[fr]);
head[fr]=cnt;
if(f)add(to,fr,0,-c,0);
}
ll d[maxn];
int fl[maxn];
int last[maxn];
int in[maxn];
int n;
inline ll mincost(){
ll ret=0;
while(1){
for(register int t=1;t<=T;++t) d[t]=1LL<<60,fl[t]=0,in[t]=0;
d[S]=0;q.push(S);fl[S]=inf;
while(q.size()){
register int now=q.front();
q.pop();
in[now]=0;
for(register int t=head[now];t;t=e[t].nx){
if(d[e[t].to]>d[now]+e[t].c&&e[t].w>0){
d[e[t].to]=d[now]+e[t].c;
fl[e[t].to]=min(e[t].w,fl[now]);
last[e[t].to]=t;
if(!in[e[t].to]) q.push(e[t].to);
in[e[t].to]=1;
}
}
}
if(fl[T]==0)break;
ret+=d[T]*fl[T];
for(register int t=T;t!=S;t=e[last[t]^1].to)
e[last[t]].w-=fl[T],e[last[t]^1].w+=fl[T];
}
return ret;
}
int r[maxn];
int main(){
n=qr();
S=n+n+1;T=n+n+2;
for(register int t=1,t1;t<=n;++t){
add(S,t,r[t]=t1=qr(),0);
add(t+n,T,t1,0);
if(t>1)add(t-1,t,inf,0);
}
int p,m,f,N,s;
p=qr();m=qr();f=qr();N=qr();s=qr();
for(register int t=1;t<=n;++t){
add(S,t+n,r[t],p);
if(t+m<=n) add(t,t+m+n,inf,f);
if(t+N<=n) add(t,t+N+n,inf,s);
}
printf("%lld\n",mincost());
return 0;
}
博客保留所有权利,谢绝学步园、码迷等不在文首明显处显著标明转载来源的任何个人或组织进行转载!其他文明转载授权且欢迎!