描述:
题意:
给你n个城市,每个城市都可以往编号比自己大的城市运送c容量为物品
每个城市可以生产最多p[i]物品,最多售卖s[i]物品
然后问你这n个城市,最多总共能卖最多多少物品。
思路:
如果数据范围小的话,那么显然是网络流,建图的话s到n个城市为减容量为p[i]的边,然后n个城市到t建容量为s[i]的边,小的编号到大的编号建容量为c的边。
但是这个过不了。
考虑最大流等于最小割,我们可以考虑dp[i][j]表示考虑i个点,我们割掉了j个汇点的最小花费。
然后转移方程就是dp[i][j]=min(dp[i-1][j-1]+s[i],dp[i-1][j]+p[i]+cj)
然后滚动数组优化一下就好了
代码:
#include <bits/stdc++.h>
#define ll __int64
using namespace std;
template<class T> void read(T&num) {
char CH; bool F=false;
for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p) {
if(!p) { puts("0"); return; }
while(p) stk[++ tp] = p%10, p/=10;
while(tp) putchar(stk[tp--] + '0');
putchar('\n');
}
const int N=1e4+10;
const ll inf=0x3f3f3f3f3f3f3f3f;
int n;
ll c,p[N],s[N],dp[2][N];
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
read(n);read(c);
for(int i=1; i<=n; i++)read(p[i]);
for(int i=1; i<=n; i++)read(s[i]);
for(int i=1; i<=n; i++){
dp[i&1][0]=dp[(i-1)&1][0]+p[i];
for(int j=1; j<i; j++)
dp[i&1][j]=min(dp[(i-1)&1][j]+j*c+p[i], dp[(i-1)&1][j-1]+s[i]);
dp[i&1][i]=dp[(i-1)&1][i-1]+s[i];
}
ll ans=inf;
for(int i=0; i<=n; i++)ans=min(ans, dp[n&1][i]);
print(ans);
return 0;
}