Batch Scheduling
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 4347   Accepted: 1992

Description

There is a sequence of N jobs to be processed on one machine. The jobs are numbered from 1 to N, so that the sequence is 1,2,..., N. The sequence of jobs must be partitioned into one or more batches, where each batch consists of consecutive jobs in the sequence. The processing starts at time 0. The batches are handled one by one starting from the first batch as follows. If a batch b contains jobs with smaller numbers than batch c, then batch b is handled before batch c. The jobs in a batch are processed successively on the machine. Immediately after all the jobs in a batch are processed, the machine outputs the results of all the jobs in that batch. The output time of a job j is the time when the batch containing j finishes.

A setup time S is needed to set up the machine for each batch. For each job i, we know its cost factor Fi and the time Ti required to process it. If a batch contains the jobs x, x+1,... , x+k, and starts at time t, then the output time of every job in that batch is t + S + (Tx + Tx+1 + ... + Tx+k). Note that the machine outputs the results of all jobs in a batch at the same time. If the output time of job i is Oi, its cost is Oi * Fi. For example, assume that there are 5 jobs, the setup time S = 1, (T1, T2, T3, T4, T5) = (1, 3, 4, 2, 1), and (F1, F2, F3, F4, F5) = (3, 2, 3, 3, 4). If the jobs are partitioned into three batches {1, 2}, {3}, {4, 5}, then the output times (O1, O2, O3, O4, O5) = (5, 5, 10, 14, 14) and the costs of the jobs are (15, 10, 30, 42, 56), respectively. The total cost for a partitioning is the sum of the costs of all jobs. The total cost for the example partitioning above is 153.

You are to write a program which, given the batch setup time and a sequence of jobs with their processing times and cost factors, computes the minimum possible total cost.

Input

Your program reads from standard input. The first line contains the number of jobs N, 1 <= N <= 10000. The second line contains the batch setup time S which is an integer, 0 <= S <= 50. The following N lines contain information about the jobs 1, 2,..., N in that order as follows. First on each of these lines is an integer Ti, 1 <= Ti <= 100, the processing time of the job. Following that, there is an integer Fi, 1 <= Fi <= 100, the cost factor of the job.

Output

Your program writes to standard output. The output contains one line, which contains one integer: the minimum possible total cost.

Sample Input

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

Sample Output

153

Source

题意:N个任务排成一个序列在一台机器上等待接连完成,这N个任务被分成若干批相邻任务。 第i个任务单独完成所需的时间是Ti。在每批任务开始前,机器需要启动时间S,而完成这批任务所需的时间是各个任务需要时间的总和(同一批任务将在同一时刻完成)。每个任务的费用是它的所用时间乘以一个费用系数Fi。请确定一个分组方案,使得总费用最小。(1 <= N <= 10000)
思路:sumT[i]表示从i到n的任务所需要的时间总和,sumF[i]表示从i到n的费用系数总和,dp[i]表示对于从i到n的任务安排的最优解:

dp[i]=min(dp[j]+(sunT[i]-sumT[j]+s)*sumF[i]) (1<=i<=n+1;i<j<=n+1)

我们考虑在计算dp[i]时,对于i < j < k来说, 如果保证决策k比决策j大的条件是:dp[j] + (S + sumT[i] - sumT[j]) * sumF[i] < dp[k] + (S + sumT[i] -sumT[k]) * sumF[i]

通过移项整理,可以化简为:(dp[j] - dp[k]) / (sumT[j] - sumT[k]) < sumF[i]

可知当我们计算dp[i]时,若(dp[j] - dp[k]) / (sumT[j] - sumT[k]) >=sumF[i]时我们可以舍弃j(决策K优于决策J);

因此我们可以用一个单调队列,对于元素i需要入对时,(i<j<k),我们如何维护呢,不妨设函数Q(j,k)=(dp[j] - dp[k]) / (sumT[j] - sumT[k]);

因为i需要入对,我们需要讨论的即是对于决策j,我们是否需要保留,(下面我们来讨论J需要舍弃的条件);

如果j需要舍弃,即对于决策i,j,i优于j;对于决策j,k,k优于j;故此我们有Q(i,j)<sumF[i],sumF[i]<=Q(j,k);  即推出 Qi,j)<Q(j,k);

综上:可以考虑维护一个斜率的队列来优化整个DP过程:

(1)假设i(马上要入队的元素)<j< k依次是队列尾部的元素,那么我们就要考虑Q(i,j)是否大于Q(j,k),如果Q(i,j) < Q(j,k),那么可以肯定j一定不会是决策点,可以从队列中将j去掉,依次向前推,直到找到一个队列元素少于2个或者Q(i,j)>= Q(j,k)的点才停止。

(2)假设k>j(k是头元素)是依次是队列头部的元素,如果g(j,k) < sumF[i]的话,那么对于i来说决策点j肯定优于决策点k,又由于sumF[i]是随着i减少而递增的,

所以当Q(j,k) < sumF[i]时,就一定有Q(j,k) < sumF[i-1],因此当前的决策点k不仅仅在考虑dp[i]时不会是最佳决策点,而且在后面的DP中也一定不会是最佳决策点,所以我们可以把k从队列 的头部删除,依次往后如此操作,直到队列元素小于2或者Q(j,k)>= sumF[i]。

代码:

 #include<sstream>
#include<iomanip>
#include"cstdio"
#include"map"
#include"set"
#include"cmath"
#include"queue"
#include"vector"
#include"string"
#include"cstring"
#include"time.h"
#include"iostream"
#include"stdlib.h"
#include"algorithm"
#define db double
#define ll long long
#define vec vectr<ll>
#define mt vectr<vec>
#define ci(x) scanf("%d",&x)
#define cd(x) scanf("%lf",&x)
#define cl(x) scanf("%lld",&x)
#define pi(x) printf("%d\n",x)
#define pd(x) printf("%f\n",x)
#define pl(x) printf("%lld\n",x)
//#define rep(i, x, y) for(int i=x;i<=y;i++)
#define rep(i, n) for(int i=0;i<n;i++)
const int N = 1e4+ ;
const int mod = 1e9 + ;
const int MOD = mod - 1;
const int inf = 0x3f3f3f3f;
const db PI = acos(-1.0);
const db eps = 1e-;
using namespace std;
ll dp[N];
int st[N],sf[N],deq[N];
int t[N],f[N];
int n,s;
db cal(int x,int y){
return db(dp[x]-dp[y])/db(st[x]-st[y]);
}
int main()
{
ci(n),ci(s);
for(int i=;i<=n;i++) ci(t[i]),ci(f[i]);
for(int i=n;i;i--) st[i]=st[i+]+t[i],sf[i]=sf[i+]+f[i];
int l=,r=;
dp[n]=(s+st[n])*sf[n];
deq[++r]=n;
for(int i=n-;i;i--)
{
while(r-l>= && cal(deq[l],deq[l+])<sf[i]) l++;
int tt=s+st[i];
tt*=sf[i];
dp[i]=tt;
int j=deq[l];
tt=s+st[i]-st[j];
tt*=sf[i];
dp[i]=min(dp[i],dp[j]+tt);
while(r-l>= && cal(deq[r-],deq[r])>cal(deq[r],i)) r--;
deq[++r]=i;
}
pl(dp[]);
return ;
}

POJ 1180 斜率优化DP(单调队列)的更多相关文章

  1. poj 1180 斜率优化dp

    这个题目要是顺着dp的话很难做,但是倒着推就很容易退出比较简单的关系式了. dp[i]=min(dp[u]+(sum[u-1]-sum[i-1]+s)*f[i]);dp[i]代表从i到结尾需要花费的代 ...

  2. 洛谷P3195 [HNOI2008] 玩具装箱 [DP,斜率优化,单调队列优化]

    题目传送门 题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N ...

  3. BZOJ_1096_[ZJOI2007]_仓库建设_(斜率优化动态规划+单调队列+特殊的前缀和技巧)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1096 有\(n\)个工厂,给出第\(i\)个工厂的到1号工厂的距离\(x[i]\),货物数量\ ...

  4. BZOJ_1010_[HNOI2008]_玩具装箱toy_(斜率优化动态规划+单调队列)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1010 给出\(n\)和\(l\).有\(n\)个玩具,第\(i\)个玩具的长度是\(c[i]\ ...

  5. 洛谷P3628 [APIO2010]特别行动队(动态规划,斜率优化,单调队列)

    洛谷题目传送门 安利蒟蒻斜率优化总结 由于人是每次都是连续一段一段地选,所以考虑直接对\(x\)记前缀和,设现在的\(x_i=\)原来的\(\sum\limits_{j=1}^ix_i\). 设\(f ...

  6. 【BZOJ 4709】柠檬 斜率优化dp+单调栈

    题意 给$n$个贝壳,可以将贝壳分成若干段,每段选取一个贝壳$s_i$,这一段$s_i$的数目为$num$,可以得到$num^2\times s_i$个柠檬,求最多能得到几个柠檬 可以发现只有在一段中 ...

  7. 算法笔记--斜率优化dp

    斜率优化是单调队列优化的推广 用单调队列维护递增的斜率 参考:https://www.cnblogs.com/ka200812/archive/2012/08/03/2621345.html 以例1举 ...

  8. [poj3017] Cut the Sequence (DP + 单调队列优化 + 平衡树优化)

    DP + 单调队列优化 + 平衡树 好题 Description Given an integer sequence { an } of length N, you are to cut the se ...

  9. POJ 3017 DP + 单调队列 + 堆

    题意:给你一个长度为n的数列,你需要把这个数列分成几段,每段的和不超过m,问各段的最大值之和的最小值是多少? 思路:dp方程如下:设dp[i]为把前i个数分成合法的若干段最大值的最小值是多少.dp转移 ...

随机推荐

  1. Chrome浏览器正常,IE下界面却乱了

    背景:项目实战中总会遇到一些小问题,IE特别多 Chrome浏览器页面正常,IE下界面就乱了 原因分析 1.首先想到的是代码有米有问题呢?主要指的是兼容性 2.兼容性没有问题,那我们打开IE的开发工具 ...

  2. tomcat多站点部署

    我们可能会有这种场景,一个tomcat想部署两个web工程,说白了就是公用一个端口,那怎么办呢?就是多站点部署,具体步骤如下(这里以linux平台举例): 1)先修改server.xml(conf/s ...

  3. 织梦dedecms去除友情链接中的li和span

    文件:/include/taglib/flink.lib.php 1.去除友链中的li if(trim($ctag->GetInnerText())=='') $innertext = &quo ...

  4. FastReport Site授权联合推广计划 彻底保障商业化开发,还送iPhone 5s

    上月慧都与报表控件开发商Fastreport联合推出的优惠活动,获得中国开发者的巨大反响.本月慧都再次发力,与Fast Reports, Inc.联合推出FastReport Site授权推广计划.活 ...

  5. C#设计模式--抽象工厂模式(创建型模式)

    一.抽象工厂模式: 在工厂模式中具体的产品和具体的工厂是一一对应的,一个工厂只能生产一种产品,结构单一,例如小米公司刚开始是只生产小米手机,但是伴随着公司的发展,他们需要生产不同型号的手机,也会生产路 ...

  6. PostgresQL中的NUlls first/last功能

    Nulls first/last功能简介Nulls first/last功能主要用于order by排序子句中,影响空值Null在排序结果中的位置.简单来说,Nulls first表示Null值在排序 ...

  7. 关于ASP.NET页面事件的知识点

    ASP是动态服务器页面(ActiveServerPage)的英文缩写,是微软公司开发的代替CGI脚本程序的一种应用,它可以与数据库和其它程序进行交互,是一种简单.方便的编程工具.那么关于ASP.NET ...

  8. MSMQ学习笔记二——创建Message Queue队列

    一.创建Message Queue队列的主要流程 1.定义MQQUEUEPROPS 结构: 2.设置消息队列属性: 3.初始化MQQUEUEPROPS 结构: 4.调用MQCreateQueue创建队 ...

  9. shell脚本监控URL并自动发邮件

    1.安装sendmail:yum install -y sendmail 2.安装mail:yum install -y mail 3.安装mutt:yum install -y mutt 4.启动s ...

  10. nginx 配置路由规则转发配置记录

    工作中公司要求针对经销商PC端和工厂PC端的访问地址固定访问. 经销商PC端 http://localhost/ 工厂PC端   http://localhost/fac 文件磁盘路径: /crm/n ...