小明升任了 CF 國的大總管,他管轄的 n 個城市,編號爲 1..n。每一個城市生產了 pi 個貨物,限制最多能夠賣掉 si 個貨物。對於每兩個城市 i, j,若是 i < j,則能夠最多從 i 運送 c 個貨物到 j。注意不能反向運送,卻能夠在多個城市之間送來送去。如今小明想知道,通過運輸後,最多能賣掉多少個貨物。c++
咱們按照題意試試建圖跑網絡流?數組
虛構源點和匯點,源點向每一個城市連邊容量爲pi,每一個城市向匯點連邊容量爲si,對於全部編號i<j的城市,i向j連邊容量爲c,跑最大流?網絡
但是數據範圍決定了,確定開不下,因此咱們得另尋他法。ide
最大流=最小割spa
並且題目裏的限制條件很是好,咱們能夠直接dp,設f[i][j]表示考慮前i個城市,將其中j個城市分到離源點近的集合,這些點的最小割是多少。咱們只須要枚舉對於一個點分在哪一個集合就行了,並且能夠開的下滾動數組,時間複雜度也是能夠的。code
代碼:xml
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int N=10005; 5 const ll inf=1e14;int n,c; 6 ll f[2][N],p[N],s[N],ans=0,mn; 7 int main(){ 8 scanf("%d%d",&n,&c); 9 for(int i=1;i<=n;i++) 10 scanf("%lld",&p[i]); 11 for(int i=1;i<=n;i++) 12 scanf("%lld",&s[i]); 13 for(int i=1;i<=n;i++){ 14 ans+=min(s[i],p[i]); 15 int x=i&1,y=(i-1)&1; 16 for(int j=0;j<=i;j++){ 17 f[x][j]=inf; 18 if(p[i]>s[i]){//供過於求 19 if(j!=i) f[x][j]=min(f[x][j], 20 f[y][j]+p[i]-s[i]+(ll)j*c); 21 if(j) f[x][j]=min(f[x][j], 22 f[y][j-1]); 23 } else{//供不該求或自產自銷 24 if(j!=i) f[x][j]=min(f[x][j], 25 f[y][j]+(ll)j*c); 26 if(j) f[x][j]=min(f[x][j], 27 f[y][j-1]+s[i]-p[i]); 28 } 29 } 30 } mn=f[n&1][0]; 31 for(int i=1;i<=n;i++) mn=min(mn,f[n&1][i]); 32 printf("%lld\n",mn+ans); 33 }