题目链接: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. cocos2d-x-3.3rc2-003 cocos中的引用计数和自己主动释放池

    点击打开链接

  2. Java获取项目路径下的方法(全)

    平时敲代码的时候,非常多时候提示文件找不到,而抛出了异常,如今整理例如以下 一 相对路径的获得 说明:相对路径(即不写明时候究竟相对谁)均可通过下面方式获得(不论是一般的java项目还是web项目) ...

  3. Swift 3.0(一)

    一:let 和 var let 声明的是一个常量, var 声明的是一个变量 二:简单数据类型 1.自推出数据类型 let implicitDouble = 70.0    //根据初始化时赋值的数据 ...

  4. thinkphp项目上传到github,为什么缺少很多文件

    thinkphp项目上传到github,为什么缺少很多文件 问题: 把tp5项目push到码云(类似github)上,为什么没有thinkphp这个核心库? 然后我看了下码云和github上,官方的t ...

  5. ElasticSearch 深入理解 三:集群部署设计

    ElasticSearch 深入理解 三:集群部署设计 ElasticSearch从名字中也可以知道,它的Elastic跟Search是同等重要的,甚至以Elastic为主要导向. Elastic即可 ...

  6. 发送HTTP请求 -- HttpUtil

    1. package com.step.utils; import java.io.IOException; import java.net.URLDecoder; import java.util. ...

  7. MetaSploit攻击实例讲解------攻击445端口漏洞(kali linux 2016.2(rolling))(详细)

    不多说,直接上干货! 大家,相信最近的这个事件,对于445端口已经是非常的小心了.勒索病毒 445端口是一个毁誉参半的端口,有了它我们可以在局域网中轻松访问各种共享文件夹或共享打印机,但也正是因为有了 ...

  8. Android PullToRefreshListView设置各个item之间的间距

    要设置第三方的上拉下载listView的item之间的间距,可以在xml布局文件中的listView节点中设置xml的属性即可: android:divider="#00000000&quo ...

  9. php正则检测字符串由单一字符组成

    $str = 'aaa' $firstChar = substr($str , 0, 1); $pattern = "/^[$firstChar]+$/"; $ret = preg ...

  10. [转载]PyCharm创建.py自动添加文件头注释

    转自:https://blog.csdn.net/qq_36482772/article/details/67218214 创建.py文件时 顺便自动添加作者.时间.文件名信息…… mac系统打开编辑 ...