batch

★☆   输入文件:batch.in   输出文件:batch.out   简单对比
时间限制:1 s   内存限制:128 MB

题目描

N个任务排成一个序列在一台机器上等待完成(顺序不得改变),这N个任务被分成若干批,每批包含相邻的若干任务。从时刻0开始,这些任务被分批加工,第i个任务单独完成所需的时间是Ti。在每批任务开始前,机器需要启动时间S,而完成这批任务所需的时间是各个任务需要时间的总和(同一批任务将在同一时刻完成)。每个任务的费用是它的完成时刻乘以一个费用系数Fi。请确定一个分组方案,使得总费用最小。

例如:S=1;T={1,3,4,2,1};F={3,2,3,3,4}。如果分组方案是{1,2}、{3}、{4,5},则完成时间分别为{5,5,10,14,14},费用C={15,10,30,42,56},总费用就是153。

输入格式

第一行是N(1<=N<=5000)。

第二行是S(0<=S<=50)。

下面N行每行有一对数,分别为Ti和Fi,均为不大于100的正整数,表示第i个任务单独完成所需的时间是Ti及其费用系数Fi

输出格

一个数,最小的总费用。

输入样

5
1
1 3
3 2
4 3
2 3

1 4

输出样

153

额  哇哇哇  dp写挂了 QAQ

正解1

f[i]   前i个任务的最优结果

f[i]=min{f[j] +sumt[i]*(sumc[i]-sumc[j])+S*(sumc[n]-sumc[j])}

好东西呢 唉 QAQ

详细题解如下:

暴力方法

由于每一批任务连续,所以预处理出两个前缀和数组:

sumt[i] 表示 执行前i个任务所需要的时间 , 即t[1]+t[2]+...+t[n]

sumc[i] 表示 不乘时间时,执行前i个任务所需要的费用 , 即c[1]+c[2]+...+c[n]

dp子状态:

dp[i][j] 表示 前i个任务分成j批所需要的最小费用。

于是可以由dp[k][j-1]推出dp[i][j]:

dp[i][j]=min{dp[k][j-1]+(s*j+sumt[i])*(sumc[i]-sumc[k])}

时间复杂度O(n^3),

空间复杂度O(n^2)。

略微优化

暴力方法的dp子状态空间是二维的,由于N <= 10000 ,所以考虑将二维状态降到一维。

将第一维去掉的想法不太实际,故考虑将第二维去掉。

首先思考所有任务都放到同一批中,观察每个任务需要等待S时间的次数:

任务编号 1  2  3  ...  n

等待次数 1  1  1  ...  1

当将1~pos1分成一个区间时,每个任务需要等待的次数变为:

任务编号 1  2  3  ...  pos1  pos1+1  ...  n

等待次数 1  1  1  ...   1      2     ...  2

(如果仍然看不出来,可以再分几次找找规律)

观察等待次数:每次多分出一个区间,区间左端点到n都需要多等待一次S时间。

故可以推出一个新的方程:

dp[i]=min{dp[j]+sumt[i]*(sumc[i]-sumc[j]+s*(sumc[n]-sumc[j]))

dp[i]并不只是前i个的时间  还要加上对后面的影响

上面其实就已经AC了  (但是老师的本意是要让我们写斜率优化)

斜率优化

当每次求dp[i]时,分别整理i,j的信息,把原来的方程进行玄学变形(移项):

dp[i]=min{dp[j]-(s+sumt[i])*sumc[j]}+sumt[i]*sumc[i[]+s*sumc[n]

去掉min函数,把dp[j]和sumc[j]看作变量,整理出dp[j]关于sumc[j]的一次函数(重要!):

dp[j]=(s+sumt[i]) * sumc[j] + (dp[i]-sumt[i]*sumc[i]-s*sumc[n])

y  =    k       *    x    +                 b

其中sumc[j]是自变量,dp[j]是因变量,s+sumt[i]是斜率,后面一串为截距。

建立一个平面直角坐标系:

每个决策j的二元组(sumc[j] , dp[j])表示坐标系中的点。

当前状态dp[i]表示直线的截距(且这条直线斜率为s+sumt[i])。

令直线过每个点可以得到解出截距,使截距最小的就是最优决策。

如图:

讨论三个决策点j1,j2,j3(j1<j2<j3)对应的坐标系中的点:

第一种情况:上凸。用眼睛观察(hhh)可知,j2此时不可能成为最佳决策点,故放弃。

第二种情况:下凹。此时j2有可能成为最佳决策点。

最后把所有可能成为最佳决策点的j处理出来,即维护一个相邻点斜率单调递增的“凸壳”。

其中最佳决策点左端斜率<s+sum[i],右端斜率>s+sum[i](可以证明这样的点只有一个)。

又因为s+sumt[i]是单调递增的,所以可以用单调队列找第一个右端斜率>s+sum[i]的点。

总时间复杂度:循环递推O(n)+单调队列O(n)=O(n)。

空间复杂度:一维状态O(n)。

#include <stdio.h>
typedef long long ll;
typedef double db;
const int N=1e6+;
int n,S,s[N],t[N],q[N],head,tail;
ll dp[N],val[N];
db k(int j,int k){return (db)(val[j]-val[k])/(s[j]-s[k]);}
int main()
{
freopen("batch.in","r",stdin);
freopen("batch.out","w",stdout);
scanf("%d%d",&n,&S);
for (int i=;i<=n;i++){
scanf("%d%d",&t[i],&s[i]);
t[i]+=t[i-];
s[i]+=s[i-];
}
q[head=tail=]=;
for (int i=;i<=n;i++){
for (;head<tail&&k(q[head],q[head+])<S+t[i];head++);
int j=q[head];
dp[i]=dp[j]+ll(s[n]-s[j])*(S+t[i]-t[j]);
val[i]=dp[i]+(ll)s[i]*t[i]-(ll)s[n]*t[i];
for (;head<tail&&k(q[tail-],q[tail])>k(q[tail],i);tail--);
q[++tail]=i;
}
printf("%lld\n",dp[n]);
return ;
}

N^2暴力AC!

#include<bits/stdc++.h>
#define maxn 5005
using namespace std;
int t[maxn],f[maxn],sumt[maxn],sumf[maxn],dp[maxn];
int main(){
// freopen("batch.in","r",stdin);freopen("batch.out","w",stdout);
int n,s;scanf("%d%d",&n,&s);
for(int i=;i<=n;i++) scanf("%d%d",&t[i],&f[i]);
for(int i=;i<=n;i++) sumt[i]=sumt[i-]+t[i],sumf[i]=sumf[i-]+f[i];
memset(dp,0x3f,sizeof(dp));
// dp[1]=t[1]*f[1]+s*(sumf[n]-sumf[1]);
dp[]=;
for(int i=;i<=n;i++)
for(int j=;j<i;j++)
dp[i]=min(dp[i],dp[j]+sumt[i]*(sumf[i]-sumf[j])+s*(sumf[n]-sumf[j]));
printf("%d",dp[n]);
//f[i]=min{f[j] +sumt[i]*(sumc[i]-sumc[j])+S*(sumc[n]-sumc[j])}
return ;
}

P2365 任务安排 batch 动态规划的更多相关文章

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

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

  2. 2018.07.09 洛谷P2365 任务安排(线性dp)

    P2365 任务安排 题目描述 N个任务排成一个序列在一台机器上等待完成(顺序不得改变),这N个任务被分成若干批,每批包含相邻的若干任务.从时刻0开始,这些任务被分批加工,第i个任务单独完成所需的时间 ...

  3. luogu P2365 任务安排(FJOI2019 batch)

    洛谷传送门 FJOI 日常原题 $2333$(似乎还不如 SDOI2012 任务安排 $2333$) 显然考虑 $dp$,这个是经典的把未来的代价先计算的 $dp$,然后才是斜率优化 一开始想状态时一 ...

  4. [洛谷P2365] 任务安排

    洛谷题目链接:任务安排 题目描述 N个任务排成一个序列在一台机器上等待完成(顺序不得改变),这N个任务被分成若干批,每批包含相邻的若干任务.从时刻0开始,这些任务被分批加工,第i个任务单独完成所需的时 ...

  5. tyvj1098[luogu 2365]任务安排 batch

    题目描述 N个任务排成一个序列在一台机器上等待完成(顺序不得改变),这N个任务被分成若干批,每批包含相邻的若干任务.从时刻0开始,这些任务被分批加工,第i个任务单独完成所需的时间是Ti.在每批任务开始 ...

  6. luogu P2365 任务安排

    嘟嘟嘟 如果常规dp,\(dp[i][j]\)表示前\(i\)个任务分\(j\)组,得到 \[dp[i][j] = min _ {k = 0} ^ {i - 1} (dp[k][j - 1] + (s ...

  7. 洛谷P2365 任务安排 [解法二 斜率优化]

    解法一:http://www.cnblogs.com/SilverNebula/p/5926253.html 解法二:斜率优化 在解法一中有这样的方程:dp[i]=min(dp[i],dp[j]+(s ...

  8. 洛谷P2365 任务安排 [解法一]

    题目描述 N个任务排成一个序列在一台机器上等待完成(顺序不得改变),这N个任务被分成若干批,每批包含相邻的若干任务.从时刻0开始,这些任务被分批加工,第i个任务单独完成所需的时间是Ti.在每批任务开始 ...

  9. 洛谷 P2365 任务安排【dp】

    其实是可以斜率优化的但是没啥必要 设st为花费时间的前缀和,sf为Fi的前缀和,f[i]为分组到i的最小花费 然后枚举j转移,考虑每次转移都是把j到i分为一组这样意味着j及之后的都要增加s的时间,同时 ...

随机推荐

  1. 1、Python 日期时间格式化输出

    今天帮朋友写自动化脚本,又需要用格式化日期,又忘记怎么写了,还是写到自己博客里面,方便日后需要的时候看一眼吧.So,临时加一篇 Python 的文章. 1.Python的time模块 import t ...

  2. [转]Jquery属性选择器(同时匹配多个条件,与或非)(附样例)

    1. 前言 为了处理除了两项不符合条件外的选择,需要用到jquery选择器的多个条件匹配来处理,然后整理了一下相关的与或非的条件及其组合. 作为笔记记录. 2. 代码 1 2 3 4 5 6 7 8 ...

  3. 2019-2-28-C#-16-进制字符串转-int-

    title author date CreateTime categories C# 16 进制字符串转 int lindexi 2019-02-28 11:51:36 +0800 2018-04-2 ...

  4. tf.train.slice_input_producer()

    tf.train.slice_input_producer处理的是来源tensor的数据 转载自:https://blog.csdn.net/dcrmg/article/details/7977687 ...

  5. P1010 数值交换

    题目描述 输入两个数 \(a\) 和 \(b\) ,将两个数交换,并输出交换后的 \(a\) 和 \(b\) . 输入格式 输入两个整数 \(a,b(1 \le a,b \le 10^6)\) 输出格 ...

  6. SpringBoot --web 应用开发之文件上传

    原文出处: oKong 前言 上一章节,我们讲解了利用模版引擎实现前端页面渲染,从而实现动态网页的功能,同时也提出了兼容jsp项目的解决方案.既然开始讲解web开发了,我们就接着继续往web这个方向继 ...

  7. Linux 内核 PCI 总线

    任何在 PCI 总线上的设备有参数 name 和 SUBSYSTEM 环境变量设置为值 pci. PCI 子系 统也一直添加下面 4 个环境变量: PCI_CLASS 设备的 PCI 类号, 16 进 ...

  8. vue-learning:26 - component - 组件三大API之一:prop

    组件三大API之一: prop prop的大小写 prop接收类型 字符串数组形式 对象形式: type / required / default / validator prop传递类型: 静态传递 ...

  9. JavaSE基础知识---常用对象API之String类

    一.String类 Java中用String类对字符串进行了对象的封装,这样的好处在于对象封装后可以定义N多属性和行为,就可以对字符串这种常见的数据进行方便的操作. 格式:(1)String s1 = ...

  10. 【23.91%】【hdu 4694】Important Sisters("支NMLGB配树"后记)(支配树代码详解)

    Time Limit: 7000/7000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total Submission( ...