zoukankan      html  css  js  c++  java
  • 题解 CF724E 【Goods transportation】

    先考虑一种网络流解法,从源点 (S) 向每个点连容量为 (p_i) 的边,每个点向汇点连容量为 (s_i) 的边,每个点向编号比其大的点连容量为 (c) 的边,该图的最大流即为答案。

    但是复杂度无法接受,考虑换一种思路,观察建出的图:

    发现这张图比较特殊,像最小割的模型,考虑将求最大流转为求最小割,用考虑 (DP) 来解决。设 (f_{i,j}) 为考虑了前 (i) 个点,有 (j) 个点与源点相连的最小割花费,得转移方程为:

    [large f_{i,j}=minleft(f_{i-1,j-1}+s_i,f_{i-1,j}+p_i+jc ight) ]

    即转移为点 (i) 是和源点相连还是和汇点相连。(DP) 数组开不下,需要用滚动数组。

    #include<bits/stdc++.h>
    #define maxn 10010
    #define inf 10000000000000000
    using namespace std;
    typedef long long ll;
    template<typename T> inline void read(T &x)
    {
        x=0;char c=getchar();bool flag=false;
        while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        if(flag)x=-x;
    }
    ll n,c,x,ans=inf;
    ll p[maxn],s[maxn],f[2][maxn];
    int main()
    {
        read(n),read(c);
        for(int i=1;i<=n;++i) read(p[i]);
        for(int i=1;i<=n;++i) read(s[i]);
        for(int i=1;i<=n;++i,x^=1)
        {
            f[x][0]=f[x^1][0]+p[i];
            for(int j=1;j<=n;++j) f[x][j]=inf;
            for(int j=1;j<=i;++j)
                f[x][j]=min(f[x^1][j-1]+s[i],f[x^1][j]+p[i]+j*c);
        }
        for(int i=0;i<=n;++i) ans=min(ans,f[x^1][i]);
        printf("%lld",ans);
        return 0;
    }
    
  • 相关阅读:
    数据库事务的四个隔离级别
    synchronized与Lock的区别
    线程池的注意事项
    守护线程与非守护线程
    wait与sleep的区别
    String,StringBuffer,StringBuilder
    2019牛客暑期多校训练营 第二场
    2019牛客暑期多校训练营 第一场
    Codeforces Round #568 (div. 2)
    Codeforces Round #570 (Div. 3)
  • 原文地址:https://www.cnblogs.com/lhm-/p/13555758.html
Copyright © 2011-2022 走看看