POJ 1180 斜率优化DP(单调队列)
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 4347 | Accepted: 1992 |
Description
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
Output
Sample Input
5
1
1 3
3 2
4 3
2 3
1 4
Sample Output
153
Source
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(单调队列)的更多相关文章
- poj 1180 斜率优化dp
这个题目要是顺着dp的话很难做,但是倒着推就很容易退出比较简单的关系式了. dp[i]=min(dp[u]+(sum[u-1]-sum[i-1]+s)*f[i]);dp[i]代表从i到结尾需要花费的代 ...
- 洛谷P3195 [HNOI2008] 玩具装箱 [DP,斜率优化,单调队列优化]
题目传送门 题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N ...
- BZOJ_1096_[ZJOI2007]_仓库建设_(斜率优化动态规划+单调队列+特殊的前缀和技巧)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1096 有\(n\)个工厂,给出第\(i\)个工厂的到1号工厂的距离\(x[i]\),货物数量\ ...
- BZOJ_1010_[HNOI2008]_玩具装箱toy_(斜率优化动态规划+单调队列)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1010 给出\(n\)和\(l\).有\(n\)个玩具,第\(i\)个玩具的长度是\(c[i]\ ...
- 洛谷P3628 [APIO2010]特别行动队(动态规划,斜率优化,单调队列)
洛谷题目传送门 安利蒟蒻斜率优化总结 由于人是每次都是连续一段一段地选,所以考虑直接对\(x\)记前缀和,设现在的\(x_i=\)原来的\(\sum\limits_{j=1}^ix_i\). 设\(f ...
- 【BZOJ 4709】柠檬 斜率优化dp+单调栈
题意 给$n$个贝壳,可以将贝壳分成若干段,每段选取一个贝壳$s_i$,这一段$s_i$的数目为$num$,可以得到$num^2\times s_i$个柠檬,求最多能得到几个柠檬 可以发现只有在一段中 ...
- 算法笔记--斜率优化dp
斜率优化是单调队列优化的推广 用单调队列维护递增的斜率 参考:https://www.cnblogs.com/ka200812/archive/2012/08/03/2621345.html 以例1举 ...
- [poj3017] Cut the Sequence (DP + 单调队列优化 + 平衡树优化)
DP + 单调队列优化 + 平衡树 好题 Description Given an integer sequence { an } of length N, you are to cut the se ...
- POJ 3017 DP + 单调队列 + 堆
题意:给你一个长度为n的数列,你需要把这个数列分成几段,每段的和不超过m,问各段的最大值之和的最小值是多少? 思路:dp方程如下:设dp[i]为把前i个数分成合法的若干段最大值的最小值是多少.dp转移 ...
随机推荐
- .Net Core 应用框架。
1.分布式系统框架 https://github.com/MassTransit/MassTransit 2.搜索引擎 https://github.com/XiLife-OSPC/Masuit. ...
- css随堂笔记(一)
Css初体验第一天 1 css初识:css主要用于设置HTML页面中文本内容,图片的外形,以及版面的布局等外观显示样式 Css样式规范:h1{属性:值} 2 css的三总书写方式:1 行内样式 将样 ...
- Window10 Bug记录
1.两台新电脑刚安装: 妹子的电脑JDK配置后,重启后环境变量配置丢失,cmd里能输出,但eclipse启动不了,重新配置后正常. 我的电脑JDK配置,重启后环境变量在,但好像没加载,cmd输出与ec ...
- Laravel 5.5 官方推荐 Nginx 配置学习
Laravel 5.5 版本官方放出了 Nginx 服务器的配置,中文文档:服务器配置 Nginx server { listen 80; server_name example.com; root ...
- navicat for mysql注册码:NAVN-LNXG-XHHX-5NOO
名.组织可以为空或任意填写. 摘自: navicat for mysql10.0.0.0注册码中“名”.“组织”...._百度知道
- graphql 数据增删改查分页及关联操作(三)
说明: 接第二篇文章,代码也是在第二篇文章之上 本文只是针对mondodb来操作 一.添加相关的包 yarn add Mongoose 二.初始化Mongodb 修改server.ts 导入 impo ...
- C语言中头文件怎么写?(本文来源网络,由黑乌鸦进一步完善)
c语言头文件怎么写?我一直有这样的疑问,但是也一直没去问问到底咋回事:所以今天一定要把它弄明白! 其实学会写头文件之后可以为我们省去不少事情,可以避免书写大量的重复代码.有利于整理思路.使代码脉络 ...
- Codeforces Round #404 (Div. 2) ABC
A. Anton and Polyhedrons Anton's favourite geometric figures are regular polyhedrons. Note that ther ...
- [论文理解]关于ResNet的进一步理解
[论文理解]关于ResNet的理解 这两天回忆起resnet,感觉残差结构还是不怎么理解(可能当时理解了,时间长了忘了吧),重新梳理一下两点,关于resnet结构的思考. 要解决什么问题 论文的一大贡 ...
- 2017.10.26 JavaWeb----第五章 JavaBean技术
JavaWeb----第五章 JavaBean技术 (1)JavaBean技术 JavaBean技术是javaweb程序的重要组成部分,是一个可重复使用的软件组件,是用Java语言编写的.遵循一定的标 ...