zoukankan      html  css  js  c++  java
  • 洛谷P2365 任务安排 [解法二 斜率优化]

    解法一:http://www.cnblogs.com/SilverNebula/p/5926253.html

    解法二:斜率优化

    在解法一中有这样的方程:dp[i]=min(dp[i],dp[j]+(sumf[i]-sumf[j])*sumt[i]+s*(sumf[n]-sumf[j]) )

    其中min的后半部分,也就是dp[j]+(sumf[i]-sumf[j])*sumt[i]+s*(sumf[n]-sumf[j]) 计算了将j~i分为一组的花费(以及提前计算的受影响花费)

    设f(j)=dp[j]+(sumf[i]-sumf[j])*sumt[i]+s*(sumf[n]-sumf[j]),i不变时,若 f(j1)<f(j2) ,显然从j1到i分为一组比j2到i分为一组的答案更优,而如果j1<j2,显然j2可以被舍弃掉。由以上两个限制条件很容易联想到单调队列,进而想到斜率优化(并不)。

    现在来考虑 j1<j2 ,f(j1)<f(j2) 的情况。把f()展开写再化简,可以得到(dp[j1]-dp[j2])/(sumf[j1]-sumf[j2])<=sumt[i]+s    (sumf和sumt分别是f、t的前缀和)

    利用这个式子列斜率方程,维护一个下凸壳即可←然而并不能理解

    我的想法:(dp[j1]-dp[j2])/(sumf[j1]-sumf[j2])显然是越小越好,我们可以据此维护斜率单调队列的队尾(具体看代码),而上面那个式子用来维护队头,即可行:

    斜率优化10ms,O(n^2)算法43ms

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<queue>
     6 #include<cstring>
     7 using namespace std;
     8 const int mxn=6000;
     9 int n;
    10 int s;
    11 int t[mxn],f[mxn];
    12 int sumt[mxn],sumf[mxn];
    13 int dp[mxn];
    14 int q[mxn];
    15 int gup(int j,int k){
    16     return (dp[j]-dp[k]);
    17 }
    18 int gdown(int j,int k){
    19     return sumf[j]-sumf[k];
    20 }
    21 int gdp(int i,int j){
    22     return dp[j]+(sumf[i]-sumf[j])*sumt[i]+s*(sumf[n]-sumf[j]);
    23 }
    24 int main(){
    25     scanf("%d%d",&n,&s);
    26     int i,j;
    27     for(i=1;i<=n;i++){
    28         scanf("%d%d",&t[i],&f[i]);
    29         sumt[i]=sumt[i-1]+t[i];
    30         sumf[i]=sumf[i-1]+f[i];
    31     }
    32     memset(dp,0x3f,sizeof dp);
    33     dp[0]=0;
    34     int hd=0,tl=0;
    35     q[hd]=0;
    36     for(i=1;i<=n;i++){
    37         while(hd<tl && gup(q[hd],q[hd+1])>=(sumt[i]+s)*gdown(q[hd],q[hd+1]) )
    38             hd++;
    39         dp[i]=gdp(i,q[hd]);
    40         while(hd<tl && gup(i,q[tl])*gdown(q[tl],q[tl-1])<=gup(q[tl],q[tl-1])*gdown(i,q[tl]) )tl--;
    41         q[++tl]=i;
    42     }
    43     printf("%d",dp[n]);
    44     return 0;
    45 }
  • 相关阅读:
    【计算机网络】物理层
    【计算机网络】计算机网络体系结构
    【计算机组成原理】存储器
    【计算机组成原理】定点数运算
    【计算机组成原理】校验码
    【计算机组成原理】数据的表示和运算
    【计算机组成原理】计算机系统概述
    【计算机组成原理】输入输出系统(一)
    【计算机组成原理】总线
    【计算机组成原理】中央处理器-硬布线控制器 流水线
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/5926270.html
Copyright © 2011-2022 走看看