• 一本通提高1607 任务安排2


    【题目描述】

    有 N 个任务排成一个序列在一台机器上等待执行,它们的顺序不得改变。机器会把这 N 个任务分成若干批,每一批包含连续的若干个任务。从时刻 0 开始,任务被分批加工,执行第i个任务所需的时间是 Ti。另外,在每批任务开始前,机器需要 S 的启动时间,故执行一批任务所需的时间是启动时间 S 加上每个任务所需时间之和。

    一个任务执行后,将在机器中稍作等待,直至该批任务全部执行完毕。也就是说,同一批任务将在同一时刻完成。每个任务的费用是它的完成时刻乘以一个费用系数 Ci 。

    请为机器规划一个分组方案,使得总费用最小。

    【输入】

    第一行是 N。第二行是 S

    下面 N 行每行有一对正整数,分别为 Ti和 Ci ,表示第 i 个任务单独完成所需的时间是 Ti 及其费用系数 Ci 。

    【输出】

    一个数,最小的总费用。

    【输入样例】

    5
    1
    1 3
    3 2
    4 3
    2 3
    1 4

    【输出样例】

    153

    【提示】

    数据范围与提示:

    对于全部数据,1≤N≤10^4,0≤S≤50,1≤Ti,Ci≤100。

    ————————————————————————————————————————————

    网上大多数都是按照一本通提高篇做的,都是从1到n枚举。我的是逆序枚举的,偏偏做的过程中出了一点点问题,没得参考了,只能自己调。幸好只是小问题!

    原先,做过这个题,不过可能是数据较水的问题用任务安排1的代码过了,这次算是正式补上斜率优化这一块!

    这个和其他不同的是,就是逆序枚举,还要维护单调性,比较不爽!

    ————————————————————————————————————————————

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e4+10;
    int n,s;
    int f[maxn],sc[maxn],smt[maxn];
    int q[maxn],l,r;
    ll y(int a)
    {
        return f[a]+sc[a]*smt[a];
    }
    long double get_xl(int a,int b)
    {
        return (long double)(y(b)-y(a))/(smt[b]-smt[a]);
    }
    int main()
    {
        scanf("%d%d",&n,&s);
        for(int t,c,i=1;i<=n;++i)
        {
            scanf("%d%d",&smt[i],&sc[i]);
            smt[i]+=smt[i-1];
            sc[i]+=sc[i-1];
        }
        for(int i=n;i>=0;--i)
        {
            while(l<r&&get_xl(q[l],q[l+1])>=sc[i])++l;
            f[i]=f[q[l]]+(sc[q[l]]-sc[i])*smt[q[l]]+(sc[n]-sc[i])*s;
            while(l<r&&get_xl(q[r-1],q[r])<=get_xl(q[r],i))--r;
            q[++r]=i;
        }
        cout<<f[0]<<endl;
        return 0;
    }
  • 相关阅读:
    H5页面与ios交互返回上一级
    url传中文参数乱码问题
    获取除当前元素外的所有类名相同的元素
    vue根据id删除某一行
    非对称加密算法
    Linux下nc命来实现文件传输
    linux下挂载第二块硬盘
    libcprops
    android开发环境安装记录
    MD(d)、MT(d)编译选项的区别
  • 原文地址:https://www.cnblogs.com/gryzy/p/14380675.html
Copyright © 2020-2023  润新知