题解:CF724E Goods transportation

可以在 cnblog 中阅读。

题意

n 座城市,第 i 座城市生产了 pi 件货物,最多可以出售 si 件货物,编号小的城市可以向编号大的城市运输至多 c 件货物,问最多能出售多少货物。

n104

分析

乍一看是一个网络流问题,可以这样建图,令 S 为源点 T 为汇点:

SpiisiT

icj(i<j)

然后跑一个最大流就可以。但这样建边第二类就会有 O(n2) 条边,寄。

模拟费用流就是应对这样的情况的。我们把最大流问题转换为最小割问题,然后考虑使用 DP 求解。

f(i,j) 表示前 i 个点,j 个点与 S 的连边未断开,注意到 (S,i)(i,T) 必断其一,则有转移:

f(i,j)=min{f(i1,j)+pi+c×jf(i1,j1)+si

分别表示:

  1. 断开 (S,i) 需要断开与前面所有未断开与 S 连边的点的连边;
  2. 断开 (i,T)

时间复杂度 O(n2)

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)

const int N=1e5+5;
int n,c;
int s[N],p[N];
int f[N];

signed main()
{
	IOS;
	cin>>n>>c;
	for(int i=1;i<=n;i++) cin>>p[i];
	for(int i=1;i<=n;i++) cin>>s[i];
	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]+c*j+p[i],f[j-1]+s[i]);
		f[0]+=p[i];
	}
	int ans=1e16;
	for(int i=0;i<=n;i++) ans=min(ans,f[i]);
	cout<<ans<<endl;
	return 0;
}

作者:tai-chi

出处:https://www.cnblogs.com/tai-chi/p/18445458

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   tai_chi  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up light_mode palette
选择主题
点击右上角即可分享
微信分享提示