题目链接:http://codeforces.com/contest/724/problem/E
考虑有非常显然的边数为${n^{2}}$的网络流做法,源点向每一个点$i$连流容量为${p_i}$的边,每一个点像汇点连容量为${s_i}$的边,每个点之间连容量为$c$的边,由于这张图比较的特殊,最大流等于最小割,所以可以考虑如何直接DP出这个最小割。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 using namespace std; 9 #define maxn 100100 10 #define llg long long 11 #define inf (llg)1e16 12 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 13 llg n,ans,f[maxn],nf[maxn],s[maxn],p[maxn],c; 14 15 inline int getint() 16 { 17 int w=0,q=0; char c=getchar(); 18 while((c<'0' || c>'9') && c!='-') c=getchar(); if(c=='-') q=1,c=getchar(); 19 while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); return q ? -w : w; 20 } 21 22 int main() 23 { 24 //yyj("Dp"); 25 cin>>n>>c; 26 for (llg i=1;i<=n;i++) p[i]=getint(); 27 for (llg i=1;i<=n;i++) s[i]=getint(); 28 for (llg i=1;i<=n;i++) 29 { 30 for (llg j=0;j<=n;j++) nf[j]=inf; 31 for (llg j=i-1;j>=0;j--) 32 { 33 nf[j+1]=min(nf[j+1],f[j]+s[i]); 34 nf[j]=min(nf[j],f[j]+j*c+p[i]); 35 } 36 for (llg j=0;j<=n;j++) f[j]=nf[j]; 37 } 38 llg ans=inf; 39 for (llg i=0;i<=n;i++) ans=min(ans,f[i]); 40 cout<<ans; 41 return 0; 42 } 43 44 //我们先枚举位置,从城市1到城市n。 45 //再枚举j,在当前位置之前有j条边连着起点且没有被割掉。 46 //f[i][j+1]=min(f[i][j+1],f[i-1][j]+s[i])-----当前位置删掉连接终点的边 47 //f[i][j]=min(f[i][j],f[i-1][j]+j*c+p[i]);------当前位置删掉连接起点的边 48 //WA-75 :没有注意最后求ans的时候要考虑j=0的情况 for (llg i=0(1);i<=n;i++) ans=min(ans,f[i]);