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

    虽然以前学过斜率优化dp但是忘得和没学过一样了。就当是重新学了。

    题意很简单(反人类),利用费用提前的思想,考虑这一次决策对当前以及对未来的贡献,设 (f_i) 为做完前 (i) 个任务的贡献,(t_i) 为时间前缀和, (c_i) 为费用前缀和,容易得到

    [f_i = Min_{0 leq j < i} (f_j + t_i (c_i - c_j) + s (c_n - c_j) ]

    直接暴力转移,时间复杂度 (O(n^2))

    考虑斜率优化,将转移关系变形为

    [f_j = (s+t_i) c_j + f_i - t_i c_i - s c_n ]

    (y=f_j, x=c_j) ,则转化为标准线性形式 (y=Ax+B)

    我们要最小化 (f_i) 就要最小化 (B)

    如果原题中每个任务的完成时间都为正数,那么转移时 (A) 是单调增的,可以用单调队列维护。

    这里任务的完成时间可以为负(很反人类嘛),在单调栈上二分即可。

    细节手推公式 + 小心写代码。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 300005;
    
    int n,s,t[N],c[N],f[N],l,r,q[N];
    
    int binsearch(int l,int r,int i) {
        while(l<r) {
            int mid = (l+r)/2;
            if((f[q[mid+1]]-f[q[mid]]) <= (s+t[i]) * (c[q[mid+1]]-c[q[mid]]))
                l = mid+1;
            else
                r = mid;
        }
        return l;
    }
    
    signed main() {
        ios::sync_with_stdio(false);
        cin>>n>>s;
        for(int i=1;i<=n;i++) cin>>t[i]>>c[i];
        for(int i=1;i<=n;i++) t[i]+=t[i-1];
        for(int i=1;i<=n;i++) c[i]+=c[i-1];
        l=1; r=1;
        memset(f, 0x3f, sizeof f);
        f[0]=0;
        for(int i=1;i<=n;i++) {
            int j = binsearch(l,r,i);
            f[i] = f[q[j]] + t[i]*(c[i]-c[q[j]]) + s*(c[n]-c[q[j]]);
            while(l<r && (f[q[r]]-f[i])*(c[q[r]]-c[q[r-1]]) >= (c[q[r]]-c[i])*(f[q[r]]-f[q[r-1]])) r--;
            q[++r] = i;
        }
        cout<<f[n]<<endl;
    }
    
  • 相关阅读:
    iPad用户使用Mac和Windows应用软件-记Parallels Access使用体验
    用ipad维护Linux服务器
    Class Model of Quick Time Plugin
    vm_write
    [转]Getting a Packet Trace
    [原]调试没有符号的 iOS 应用
    [转]编译 JavaScriptCore For iOS
    [转]ARM64 Function Calling Conventions
    [转]如何选择职业道路
    [转]Native Java Bytecode Debugging without Source Code
  • 原文地址:https://www.cnblogs.com/mollnn/p/12243060.html
Copyright © 2011-2022 走看看