题目链接:http://poj.org/problem?id=1180

题目描述:

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

 
看不懂题面的随便找一个翻译软件翻译一下效果都还是不错的,至少看得懂题
 
下面直接解题:
解法一:求出T,C的前缀和sumT和sumC,设f(i,j)表示把前i个任务分成j批去执行的最小费用,状态转移方程为
f(i,j)=min(0<=k<i){f(k,j-1)+(s*j+sumT[i])*(sumC[i]-sumC[k])}
时间复杂度为O(N3)
解法二:
本题其实没有规定把任务分成多少批,也就是说解法一其实有无用的状态
现在我们设f(i)表示把前i个任务分成若干批处理的最小费用,状态转移方程为
f[i]=min(0<=j<i){f[j]+sumT[i]*(sumC[i]-sumC[j])+s*(sumC[N]-sumC[j])}
这种思想叫做“费用提前计算”,先把每次s的贡献直接加起来
时间复杂度O(N2)
解法三:
我们考虑到这题的数据,对解法二的状态转移方程进行斜率优化。
去掉min,通过移项我们可以得到f[j]=(s+sumT[i])*sumC[j]+f[i]-sumT[i]*sumC[i]-s*sumC[N]
我们发现,在以sumC[j]为横坐标,f[j]为纵坐标的坐标系中,这是条以(s+sumT[i])为斜率,f[i]-sumT[i]*sumC[i]-s*sumC[N]为截距的直线
由于-sumT[i]*sumC[i]-s*sumC[N]是一个常数,斜率也是一个固定的值,这是一个线性规划问题,我们每次取最小的截距
对于点集(sumC[j],f[j])我们其实只需要维护一个下凸壳就行了。当我们需要找到当前的最优的点时,设k=s+sumT[i],最优的点和它左边的点的斜率比k小,和它右边的斜率比k大,参考下面的图。
 
另外我们还发现一点,由于sumC具有单调性,每次加入的点都会在最右边。并且sumT同样具有单调性,这说明斜率是递增的。因此我们只需要维护比当前斜率大的一条条线段,可以通过一个单调队列q来实现
具体操作如下:
1.检查队头的两个决策变量q[l]和q[l+1],斜率f[q[l+1]]-f[q[l]]/(sumC[q[l+1]]-sumC[q[l]])<=s+sumT[i],则把q[l]出队,继续检查新的队头。
2.直接取队头j=q[l]作为最优策略,执行状态转移,得到f[i]
3.把新决策i从队尾插入,在插入之前,若三个决策点j1=q[r-1],j2=q[r],j3=i不满足斜率单调递增(不满足下凸性,即i是无用决策),则直接从队尾把q[r]出队,继续检查新的队尾。
整个算法的时间复杂度O(N),完美的解决问题。
 
下面附上代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std; const int maxn=1e4+;
int n,s;
int sumt[maxn],sumc[maxn],q[maxn];
ll f[maxn];
int main()
{
scanf("%d%d",&n,&s);
for (int i=;i<=n;i++)
{
int t,c;
scanf("%d%d",&t,&c);
sumt[i]=sumt[i-]+t;
sumc[i]=sumc[i-]+c;
}
int l=,r=;
for (int i=;i<=n;i++)
{
while (l<r&&(f[q[l+]]-f[q[l]])<=(s+sumt[i])*(sumc[q[l+]]-sumc[q[l]])) l++;
f[i]=f[q[l]]-(s+sumt[i])*sumc[q[l]]+sumt[i]*sumc[i]+s*sumc[n];
while (l<r&&(f[q[r]]-f[q[r-]])*(sumc[i]-sumc[q[r]])>=(f[i]-f[q[r]])*(sumc[q[r]]-sumc[q[r-]])) r--;
q[++r]=i;
}
printf("%lld",f[n]);
return ;
}

声明:本博客内容参考李煜东算法竞赛进阶指南

POJ1180 Batch Scheduling 解题报告(斜率优化)的更多相关文章

  1. [POJ1180&POJ3709]Batch Scheduling&K-Anonymous Sequence 斜率优化DP

    POJ1180 Batch Scheduling Description There is a sequence of N jobs to be processed on one machine. T ...

  2. POJ-1180 Batch Scheduling (分组求最优值+斜率优化)

    题目大意:有n个任务,已知做每件任务所需的时间,并且每件任务都对应一个系数fi.现在,要将这n个任务分成若干个连续的组,每分成一个组的代价是完成这组任务所需的总时间加上一个常数S后再乘以这个区间的系数 ...

  3. POJ1180 Batch Scheduling -斜率优化DP

    题解 将费用提前计算可以得到状态转移方程: $F_i = \min(F_j + sumT_i * (sumC_i - sumC_j) + S \times (sumC_N - sumC_j)$ 把方程 ...

  4. poj1180 Batch Scheduling

    Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3590   Accepted: 1654 Description There ...

  5. 【LeetCode】1029. Two City Scheduling 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 小根堆 排序 日期 题目地址:https://lee ...

  6. P2365 任务安排 / [FJOI2019]batch(斜率优化dp)

    P2365 任务安排 batch:$n<=10000$ 斜率优化入门题 $n^{3}$的dp轻松写出 但是枚举这个分成多少段很不方便 我们利用费用提前的思想,提前把这个烦人的$S$在后面的贡献先 ...

  7. LeetCode :1.两数之和 解题报告及算法优化思路

    最近开始重拾算法,在 LeetCode上刷题.顺便也记录下解题报告以及优化思路. 题目链接:1.两数之和 题意 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 ...

  8. poj 1180 Batch Scheduling (斜率优化)

    Batch Scheduling \(solution:\) 这应该是斜率优化中最经典的一道题目,虽然之前已经写过一道 \(catstransport\) 的题解了,但还是来回顾一下吧,这道题其实较那 ...

  9. POJ 1180 Batch Scheduling(斜率优化DP)

    [题目链接] http://poj.org/problem?id=1180 [题目大意] N个任务排成一个序列在一台机器上等待完成(顺序不得改变), 这N个任务被分成若干批,每批包含相邻的若干任务. ...

随机推荐

  1. 赵雅智_使用SQLiteDatabase操作SQLite数据库及事务

    知识点具体解释:http://blog.csdn.net/zhaoyazhi2129/article/details/9025995 详细代码: MainActivity.java package c ...

  2. MFC 加入背景图片并让控件背景透明

    /*加入背景图片*/ BOOL CTOOLDlg::OnEraseBkgnd(CDC* pDC) {  // TODO: 在此加入消息处理程序代码和/或调用默认值  CDialog::OnEraseB ...

  3. UE4在VS2013中各个编译配置代表意义

    UE4中有个各式各样的编译配置,都怎么个意思呢? 对原文的理解和翻译. https://docs.unrealengine.com/latest/INT/Programming/Development ...

  4. 终结者:负载均衡之Nginx(一)

            相信非常多人都听过Nginx.这个小巧的东西能够和Apache及IIS相媲美.那么它有什么作用呢?一句话.它是一个减轻Web应用server(如Tomcat)压力和实现Web应用ser ...

  5. HTML5中x-webkit-speech语音输入功能

    如今各大站点都在搜索框中增加了语音输入功能,只是眼下仅仅有Chrome 11及以上版本号才支持. 能够用chrome浏览器在这里试试效果,点击话筒就可以: 实现起来也很easy,为input加入名为 ...

  6. ios学习--第三方框架-MBProgressHUD以及扩展

    MBProgressHUD提示框官网地址:https://github.com/jdg/MBProgressHUD 一. 模式 首先, MBProgressHUD有以下几种视图模式. typedef ...

  7. iOS开发—在@interface,@implementation和@property中变量的定义

    一直搞不懂在OC中变量在@interface和@implementation中有什么区别,定义@property又有什么不同,查了很多资料,总结如下: //ViewController.h @inte ...

  8. Objective-C —内存管理(上)

    内存管理 一.为什么要进行内存管理 移动设备的内存极其有限,每个app所能占用的内存是有限制的 下列行为都会增加一个app的内存占用 创建一个OC对象 定义一个变量 调用一个函数或者方法 内存占用多大 ...

  9. yum概述配置

    YUM(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器.基于RPM包管理,能够从指定的服务器自动下载 ...

  10. (转载)BeanUtils.copyProperties() 用法

    BeanUtils.copyProperties() 用法 标签: hibernateuserjdbc数据库strutsjava 2009-10-17 23:04 35498人阅读 评论(6) 收藏  ...