zoukankan      html  css  js  c++  java
  • [SDOI2012]任务安排

    [题目链接]

             https://www.lydsy.com/JudgeOnline/problem.php?id=2726

    [算法]

            此题与POJ1180非常相似 

            但是 , 此题中的t值可能为负 , 这意味着不能每次都将斜率 <= k的点弹出 , 而需要在凸壳中进行二分查找

            时间复杂度 : O(NlogN)

    [代码]

            

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1e6 + 10;
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    
    int n , S , l , r;
    ll sumc[N] , sumt[N] , f[N];
    int q[N] , c[N] , t[N];
    
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    inline int _binary_search(int L , int R , int val)
    {
            int l = L , r = R , ret = L;
            while (l <= r)
            {
                    int mid = (l + r) >> 1;
                    if (f[q[mid + 1]] - f[q[mid]] <= val * (sumc[q[mid + 1]] - sumc[q[mid]]))
                    {
                            ret = mid + 1;
                            l = mid + 1;        
                    }    else r = mid - 1;
            }        
            return ret;
    }
    
    int main()
    {
            
            read(n); read(S);
            for (int i = 1; i <= n; i++)
            {
                    read(t[i]);
                    read(c[i]);
                    sumt[i] = sumt[i - 1] + t[i];
                    sumc[i] = sumc[i - 1] + c[i];
            }
            f[q[l = r = 1] = 0] = 0;
            for (int i = 1; i <= n; i++)
            {
                    int pos = _binary_search(l , r - 1 , S + sumt[i]);
                    f[i] = f[q[pos]] - sumc[q[pos]] * (S + sumt[i]) + sumt[i] * sumc[i] + S * sumc[n];
                    while (l < r && (f[i] - f[q[r]]) * (sumc[q[r]] - sumc[q[r - 1]]) <= (f[q[r]] - f[q[r - 1]]) * (sumc[i] - sumc[q[r]])) --r;
                    q[++r] = i;         
            }
            printf("%lld
    " , f[n]);
            
            return 0;
        
    }
  • 相关阅读:
    【linux】驱动-13-阻塞与非阻塞
    【linux】驱动-12-并发与竞态
    【linux】驱动-11-gpio子系统
    【linux】驱动-10-pinctrl子系统
    【linux】驱动-9-设备树插件
    手写Java分页模块
    JDBC连接与自定义线程池
    类加载器
    网络编程之TCP
    网络编程之UDP
  • 原文地址:https://www.cnblogs.com/evenbao/p/10354184.html
Copyright © 2011-2022 走看看