Codeforces 724E - Goods transportation
Published on 2016-10-09描述
有 座城市,每座城市有 个单位的物品,能够售出 个单位的物品,同时,对于任意 ,你都可以从 向 运送 单位的物品(不可以从 往 运),请问最多能够卖出多少个单位的物品?
分析
此题可用最大流来建模,建立附加源汇 ,对于每个城市 ,连边 ,连边 。对于每个 ,连边 ,求出 的最大流就是答案。不过 级别的边数显然会 TLE。
注意到最大流等于最小割,所以我们求出最小割,也就是求出了最大流。本题的构图比较规则,所以导致了割只可能是 ,可用 DP 来求解。
设 为考虑点 ,从中选 个点放在 中的最小代价,那么有 ,,方程也很好得出:
答案是 。采用滚动数组,就能在 的时间, 的空间内完成计算。
技巧:最大流等于最小割,在比较特殊的构图中,最小割可用 DP 求出,此时无需做网络流算法即可求出最大流。
代码
// Created by Sengxian on 2016/10/09. // Copyright (c) 2016年 Sengxian. All rights reserved. // Codeforces 724E 网络流 + 最小割 DP #include <bits/stdc++.h> using namespace std; typedef long long ll; inline int ReadInt() { static int n, ch; n = 0, ch = getchar(); while (!isdigit(ch)) ch = getchar(); while (isdigit(ch)) n = n * 10 + ch - '0', ch = getchar(); return n; } const int MAX_N = 10000 + 3; int n, c, p[MAX_N], s[MAX_N]; ll dp[MAX_N]; int main() { #ifndef ONLINE_JUDGE freopen("test.in", "r", stdin); #endif n = ReadInt(), c = ReadInt(); for (int i = 1; i <= n; ++i) p[i] = ReadInt(); for (int i = 1; i <= n; ++i) s[i] = ReadInt(); memset(dp, 0x3f, sizeof dp); dp[0] = 0; for (int i = 1; i <= n; ++i) { for (int j = i; j > 0; --j) dp[j] = min(dp[j] + (ll)c * j + p[i], dp[j - 1] + s[i]); dp[0] += p[i]; } printf("%lld\n", *min_element(dp, dp + n + 1)); return 0; }