CF2097F
思路
考虑网络流。对第 天的第 个机场建点 。 向 连边权为 。 向 连 , 向 连 , 向 连 。 向 连 。最后依次求 的最大流。
直接流跑不动,因为 到 的流量变化可以比较大。
最大流转最小割,分层状压。设 表示当 与 的连通状态为 时,所需要的最小割。。注意到 只有和相邻的位置有边,可以逐位考虑 的变化。设辅助转移数组 表示考虑了前 个位置,其中 的前 位表示第 层的状态,后面的位表示第 层的状态,转移时需要额外记录第 层 和 的状态。
复杂度 。
code
int n,m,a[maxn],b[maxn],c[maxn];
int f[1<<maxn],g[maxn][1<<maxn][2];
inline void chkmn(int &u,int v){(u>v)&&(u=v);}
void work(){
n=read();m=read();
for(int i=0;i<n;i++)a[i]=read();
for(int s=0;s<(1<<n);s++){
f[s]=0;for(int i=0;i<n;i++)if(!(s&(1<<i)))f[s]+=a[i];
}
for(int i=1;i<=m;i++){
for(int i=0;i<n;i++)a[i]=read();
for(int i=0;i<n;i++)b[i]=read();
for(int i=0;i<n;i++)c[i]=read();
for(int i=0;i<=n;i++){
for(int s=0;s<(1<<n+1);s++)g[i][s][0]=g[i][s][1]=inf;
}
for(int s=0;s<(1<<n);s++)g[0][s|((s&1)<<n)][(s>>n-1)&1]=f[s];
for(int i=0,j=n-1,k=1;i<n;i++,j=(j==n-1?0:j+1),k=(k==n-1?0:k+1)){
auto calc=[&](bool fl1,bool fl2,bool fl3,bool fl){
if(fl)return 0;
return fl1*c[j]+fl2*b[i]+fl3*a[k];
};
for(int s=0;s<(1<<n+1);s++){
for(int fl=0;fl<2;fl++)if(g[i][s][fl]<=inf){
chkmn(g[i+1][s][(s>>i)&1],g[i][s][fl]+calc(fl,(s>>i)&1,(s>>i+1)&1,(s>>i)&1));
chkmn(g[i+1][s^(1<<i)][(s>>i)&1],g[i][s][fl]+calc(fl,(s>>i)&1,(s>>i+1)&1,((s>>i)&1)^1));
}
}
}
for(int s=0;s<(1<<n);s++){
f[s]=min({g[n][s][0],g[n][s][1],g[n][s|(1<<n)][0],g[n][s|(1<<n)][1]});
}
write(f[0]),puts("");
}
}