CodeForces 724E(Goods transportation 最小割)

前言:

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

分析:

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

dp[i][j]=min(dp[i1][j1]+s[i],dp[i1][j]+jc+p[i])
,其中 dp[i][j] 表示前 i 个点选j个作为 S <script type="math/tex" id="MathJax-Element-156">S</script>的集合的流量。

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

代码:

#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值