CF724E Goods transportation

題意:

  小明升任了 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 }
dp
相關文章
相關標籤/搜索