您的位置:首页 > 编程语言 > Go语言

CodeForces 724E(Goods transportation 最小割)

2016-10-13 23:18 302 查看

前言:

基本没写过网络流的题,这题居然不知道怎么建图,蠢哭。。。

分析:

其实建一个S,指向所有的点,边权为p[i],建一个T,所有节点指向T,边权是s[i],各个点之间的边权是c,那么题目就是一道S到T的最大流。由于边存不下来,所有用最小割写。

dp[i][j]=min(dp[i−1][j−1]+s[i],dp[i−1][j]+j∗c+p[i]),其中dp[i][j]表示前i个点选j个作为S的集合的流量。

由于会爆内存,所以用滚动数组写。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <algorithm>

using namespace std;

typedef long long   LL;
typedef pair <int, int>     PII;
typedef vector <int>    VI;

#define FOR(i, x, y)    for(int i = x; i < y; ++ i)
#define IFOR(i, x, y)   for(int i = x; i > y; -- i)
#define pb  push_back
#define mp  make_pair
#define fi  first
#define se  second
#define lrt rt<<1
#define rrt rt<<1|1
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r

const int maxn = 10010;
const LL inf = 1LL << 60;

int n, p[maxn], s[maxn], c;

LL dp[maxn];

int main() {
while(~scanf("%d%d", &n, &c)) {
FOR(i, 1, n+1)  scanf("%d", p+i);
FOR(i, 1, n+1)  scanf("%d", s+i);
FOR(i, 0, n+1)  dp[i] = inf;
dp[0] = 0;
FOR(i, 1, n+1) {
IFOR(j, i+1, 0) {
dp[j] = min(dp[j-1]+s[i], dp[j]+(LL)j*c+p[i]);
}
dp[0] = dp[0]+p[i];
}
LL ans = dp[0];
FOR(i, 1, n+1)  ans = min(ans, dp[i]);
printf("%I64d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  网络流 dp codeforces