• [斜率优化DP][二分]JZOJ 3169 生产汽车


    Description

    如前面提到,ABC的汽车工厂有N个工人,他们在一个传送带上生产汽车,工人从左到右排列,编号依次为1到N,采用流水线模式,每个人负责自己的一部分工作。

    生产一台汽车需要从1号工人开始,当1号完成他的工作后,2号就会开始工作,然后是3号,最后当N号工人完成他的工作后,整个汽车生产完毕。工人们一共需要生产M台汽车,而且必须按照从1到M的顺序去生产。

    对于工人i,他完成自己的工作需要Ti的时间,而对于汽车j,组装复杂度为Fj。那么工人i花在汽车j上的时间为Ti*Fj。

    当某个工人完成他的工作后,他会同时把汽车交给下一个工人,没有任何时间上的延迟,因此,要保证下一个要接受汽车的工人必须是空闲的。为了满足这个要求,ABC需要为每一台汽车选择一个好时机开始制造。

    ABC想知道生产完所有汽车最少需要多少时间。
     

    Input

    第一行输入两个整数:工人数N(1<=N<=100,000)和汽车数M(1<=M<=100,000)。

    接下来N行描述每一个工人的Ti(1<=Ti<=10,000)。

    接下来M行描述每一台汽车的Fj(1<=Fj<=10,000)。

    Output

    输出一个数表示最少需要的时间。
     

    Sample Input

    输入1:
    3 3
    2
    1
    1
    2
    1
    1

    输入2:
    3 3
    2
    3
    3
    2
    1
    2

    输入3:
    4 5
    3
    2
    2
    2
    3
    1
    2
    1
    2
     

    Sample Output

    输出1:
    11

    输出2:
    29

    输出3:
    55
     

    Data Constraint

    40%的数据满足N,M<=1000。
     

    Hint

    样例1: 4分钟后,工人1完成1号汽车的工作,他可以立刻开始生产第2台汽车,但如果这样的话将会不满足条件,因为7分钟后,工人2完成2号汽车的工作,此时3号工人还在生产1号汽车,3号工人并不空闲,所以2号汽车在5分钟后开始生产,3号汽车在7分钟后开始生产。3台汽车全部生产完共花费11分钟。

    分析

     https://blog.csdn.net/JacaJava/article/details/78998056 不太会用博客园的数学公式,就把教我的大佬的博客贴一下8

    #include <iostream>
    #include <cstdio>
    using namespace std;
    typedef long long ll;
    const int N=1e5+10;
    int n,m,q[N];
    ll f[N],t[N],p[N];
    int tail;
    
    double xl(int i,int j) {
        return (double)(t[i]-t[j])/(t[i-1]-t[j-1]);
    }
    
    int main() {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++) scanf("%lld",&t[i]),t[i]+=t[i-1];
        for (int i=1;i<=m;i++) scanf("%lld",&f[i]);
        q[++tail]=1;
        for (int i=1;i<=n;i++) {
            while (tail>1&&xl(i,q[tail])>xl(q[tail],q[tail-1])) tail--;
            q[++tail]=i;
        }
        for (int i=2;i<=m;i++) {
            int l=1,r=tail,mid;
            double o=(double)f[i]/f[i-1];
            while (l<r) {
                mid=l+r>>1;
                if (o<xl(q[mid+1],q[mid])) l=mid+1; else r=mid;
            }
            p[i]=p[i-1]+f[i-1]*t[q[l]]-f[i]*t[q[l]-1];
        }
        printf("%lld",p[m]+f[m]*t[n]);
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    树上莫队学习笔记
    点分治学习笔记
    7.11总结
    线段树合并学习笔记
    7.10总结
    bzoj1201: [HNOI2005]数三角形----递推+bitset
    bitset(01串)优化
    Tarjan系列1
    bsgs(Baby Steps Giant Steps)算法
    [SD2015]序列统计——solution
  • 原文地址:https://www.cnblogs.com/mastervan/p/10776022.html
Copyright © 2020-2023  润新知