zoukankan      html  css  js  c++  java
  • 洛谷P2365 任务安排(斜率优化dp)

    传送门

    思路:
    最朴素的dp式子很好考虑:设(dp(i,j))表示前(i)个任务,共(j)批的最小代价。
    那么转移方程就有:

    [dp(i,j)=min{dp(k,j-1)+(sumT_i+S*j)*(sumC_i-sumC_k)} ]

    为什么有个(S*j)呢,因为前面的批次启动会对后面的答案有影响。
    但是分析复杂度是(O(n^3))的,肯定不行。
    考虑一下为什么需要第二个状态呢?是为了消除后效性,因为后面的状态不知道总共启动了几次。
    但我们可以把费用提前计算,一次启动,那么对于后面所有的机器都会有贡献,我们提前把这个贡献算了,后面就可以不管这个了,也就是强制消除后效性
    所以变换后的(dp)式子就为:

    [dp(i)=min{dp(j)+sumT_i*(sumC_i-sumC_j)+S*(sumC_n-sum_j)} ]

    其实这样已经可以通过洛谷的数据了,但这还不够!我们还可以优化。
    观察(dp)式子,后面加上的部分为(i,j)相关变量的乘积形式,所以我们可以考虑斜率优化dp。
    (i,j)变量分离,有:

    [dp(j)=(s+sumT_i)*sumC_j+dp_i-sumT_i*sumC_i-s*sumC_n ]

    显然这个式子直接用队列维护一个斜率不断增加的下凸壳即可。
    时间复杂度就为(O(n))了。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 5005, MOD = 1e9 + 7;
    int n, s;
    int sumt[N], sumc[N];
    int q[N], dp[N];
    int main() {
    #ifdef heyuhhh
        freopen("input.in", "r", stdin);
    #else
        ios::sync_with_stdio(false); cin.tie(0);
    #endif
        cin >> n >> s;
        for(int i = 1; i <= n; i++) {
            int t, c; cin >> t >> c;
            sumt[i] = sumt[i - 1] + t;
            sumc[i] = sumc[i - 1] + c;
        }
        int l = 1, r = 1; q[1] = 0;
        for(int i = 1; i <= n; i++) {
            while(l < r && dp[q[l + 1]] - dp[q[l]] <= (s + sumt[i]) * (sumc[q[l + 1]] - sumc[q[l]])) ++l;
            dp[i] = dp[q[l]] - sumt[i] * sumc[q[l]] - s * sumc[q[l]] + sumt[i] * sumc[i] + s * sumc[n];
            while(l < r && (dp[i] - dp[q[r]]) * (sumc[q[r]] - sumc[q[r - 1]]) <= (dp[q[r]] - dp[q[r - 1]]) * (sumc[i] - sumc[q[r]])) --r;
            q[++r] = i;
        }
        cout << dp[n];
        return 0;
    }
    
    
  • 相关阅读:
    awk 使用shell 变量
    设计模式之 外观(门面)模式 Facade
    设计模式之 抽象工厂模式
    python 第一课
    Visual Basic 图片连接地址添加
    smarty 不同模板 缓存时间
    PHP 传参过滤
    Nginx 0.7.x + PHP 5.2.10(FastCGI)搭建支持高并发量的Web服务器
    linux vi 编辑命令
    PHP 命令模式 执行文件 并传递参数
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/11415406.html
Copyright © 2011-2022 走看看