**
[题解] CF724E Goods transportation
**
网络流做法:
就是从源点
S
S
S 向每个城市
i
i
i 连权值为
p
i
p_i
pi 的边,从城市
i
i
i 向汇点
T
T
T 连权值为
s
i
s_i
si 的边,当
i
<
j
i<j
i<j时从城市
i
i
i 向城市
j
j
j 连权值为
c
c
c 的边,求最大流即可
因为最大流等于最小割,所以考虑如何找最小割
断开一个点连接原点和汇点的路径
方案一:断开与原点 S S S 的边,同时也要断开连接其他编号比 i i i 小且与 S S S 连接的点的边
方案二:断开与汇点 T T T 的边
考虑使用dp, f i , j f_{i,j} fi,j 表示前 i i i 个点已经断开,但是编号比 i i i 小的有 j j j 个点与 S S S 连接
使用方案一: f i , j = f i − 1 , j + p i + c ∗ j f_{i,j}=f_{i-1,j}+p_i+c*j fi,j=fi−1,j+pi+c∗j
使用方案二: f i , j = f i − 1 , j − 1 + s i f_{i,j}=f_{i-1,j-1}+s_i fi,j=fi−1,j−1+si
核心代码:
注意开long long
signed main(){
n=read(),c=read();
for(int i=1;i<=n;i++)p[i]=read();
for(int i=1;i<=n;i++)s[i]=read();
for(int i=1;i<=n;i++){
f[i]=f[i-1]+s[i];
for(int j=i-1;j>=1;j--)f[j]=min(f[j-1]+s[i],f[j]+p[i]+c*j);
f[0]+=p[i];}
for(int i=0;i<=n;i++)ans=min(ans,f[i]);
printf("%lld\n",ans);
return 0;
}