分析:
给出N个城市,每个城市有一个生产量P[i],和一个销售量S[i],然后可以从序号小的城市往序号大的城市运输货物,每对城市只能运输一次,每次最多运c个单位的货物。求最大交易量。题解:
我们很容易想到网络流建图然后跑一遍最大流求解,但是这个图里边的数量太多,肯定会MLE和TLE。因为最大流等于最小割,所以我们可以尝试去求这个网络流里的最小割,这个图里的点最终会被我们分成两边,一边的点S[i] < P[i],一边的点P[i] < S[i],所以我们设DP[i][j]表示前i个点里有j个点供应量小于销售量时的最大交易量。
状态转移方程:
dp[i][j] = min(dp[i-1][j-1]+s[i], dp[i-1][j]+p[i]+j*c)AC代码:
/*************************************************************************
> File Name: test.cpp
> Author: Akira
> Mail: qaq.febr2.qaq@gmail.com
************************************************************************/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <set>
#include <list>
#include <ctime>
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
#define MST(a,b) memset(a,b,sizeof(a))
#define CLR(a) MST(a,0)
#define Sqr(a) ((a)*(a))
using namespace std;
#define MaxN 100000
#define MaxM MaxN*10
#define INF (LL)(1e18)
#define bug cout<<88888888<<endl;
#define MIN(x,y) (x<y?x:y)
#define MAX(x,y) (x>y?x:y)
int n;
LL c;
LL P[MaxN];
LL S[MaxN];
LL dp[2][MaxN];
int main()
{
while(~scanf("%d%d", &n, &c))
{
for(int i=1;i<=n;i++) scanf("%I64d", &P[i]);
for(int i=1;i<=n;i++) scanf("%I64d", &S[i]);
for(int i=0;i<=n;i++) dp[0][i] = INF;
dp[0][0] = 0;
int now = 0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=n;j++) dp[now^1][j] = INF;
for(LL j=0;j<i;j++)
{
dp[now^1][j] = min(dp[now^1][j], dp[now][j]+P[i]+j*1ll*c);
dp[now^1][j+1] = min(dp[now^1][j+1], dp[now][j]+S[i]);
}
now^=1;
}
LL ans = *min_element(dp[now], dp[now]+n+1);
printf("%I64d\n",ans);
}
// system("pause");
}