• Goods transportation


    题目来源:codeforces 724E

    Description

    There are n cities located along the one-way road. Cities are numbered from 1 to n in the direction of the road.

    The i-th city had produced pi units of goods. No more than si units of goods can be sold in the i-th city.

    For each pair of cities i and j such that 1 ≤ i < j ≤ n you can no more than once transport no more than c units of goods from the city i to the city j. Note that goods can only be transported from a city with a lesser index to the city with a larger index. You can transport goods between cities in any order.

    Determine the maximum number of produced goods that can be sold in total in all the cities after a sequence of transportations.

    Input

    The first line of the input contains two integers n and c (1 ≤ n ≤ 10 000, 0 ≤ c ≤ 109) — the number of cities and the maximum amount of goods for a single transportation.

    The second line contains n integers pi (0 ≤ pi ≤ 109) — the number of units of goods that were produced in each city.

    The third line of input contains n integers si (0 ≤ si ≤ 109) — the number of units of goods that can be sold in each city.

    Output

     Print the maximum total number of produced goods that can be sold in all cities after a sequence of transportations.

    Sample Input

    3 0
    1 2 3
    3 2 1

    5 1
    7 4 2 1 0
    1 2 3 4 5

    4 3
    13 10 7 4
    4 7 10 13

    Sample Output

    4

    12

    34

    解题思路

      首先考虑暴力,直接跑最大流。这显然是过不了的。由于最大流等于最小割。于是我们可以将原问题转换为在建好的最大流图上求最小割。考虑当前做到第i个点,之前有j个点跟S相连。那么接下来的转移要么割掉i->T,跟S相连的点个数加一;要么割掉S->i和p_j->i,跟S相连的点个数不变。

      注意:不能同时割S->i和i->T,因为这样i还是和S联通,还不如只割i->T。数据范围较大,需要滚动数组。

      时间复杂度O(n^2)。

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    const int N = 10100;
    
    ll ans,c,f[N],g[N],INF;
    int n,p[N],s[N];
    int main(){
        INF = 0x3fffffffffffffff;ans = INF;
        scanf("%d%I64d
    ",&n,&c);
        for (int i = 1;i <= n;i++) scanf("%d",&p[i]);
        for (int i = 1;i <= n;i++) scanf("%d",&s[i]);
        for (int i = 1;i <= n;i++){
            f[0] = g[0]+p[i];
            for (int j = 1;j <= i;j++) 
                f[j] = min(g[j-1]+s[i],g[j]+p[i]+c*j);
            for (int j = 0;j <= i;j++)
                g[j] = f[j];
            g[i+1] = INF;
        }
        for (int i = 0;i <= n;i++) ans = min(ans,f[i]);
        cout << ans;
        return 0;
    }

    后记

      感觉可能配图会更清楚一些,然而懒癌发作orz题目翻译也以后再说好了。

      因为原题有三组样例,一开始没考虑到(其实是嫌麻烦),于是就用空行隔开了事。

  • 相关阅读:
    linux驱动开发学习一:创建一个字符设备
    如何高效的对有序数组去重
    找到缺失的第一个正整数
    .NET不可变集合已经正式发布
    中国人唯一不认可的成功——就是家庭的和睦,人生的平淡【转】
    自己动手搭建 MongoDB 环境,并建立一个 .NET HelloWorld 程序测试
    ASP.NET MVC 中如何用自定义 Handler 来处理来自 AJAX 请求的 HttpRequestValidationException 错误
    自己动手搭建 Redis 环境,并建立一个 .NET HelloWorld 程序测试
    ServiceStack 介绍
    一步一步实战扩展 ASP.NET Route,实现小写 URL、个性化 URL
  • 原文地址:https://www.cnblogs.com/victbr/p/6507261.html
Copyright © 2020-2023  润新知