BTW:

刚在图书馆借了本算法艺术与信息学竞赛. 我多次有买这本书的冲动, 但每次在试看之后就放弃了, 倒不是因为书太难, 而是写的实在是太差. 大家对这本书的评价很高, 我觉得多是因为书的内容, 而作者表达内容与思想的方式真是令我恼火. programmer 写博客, 尤其是技术博客, 往往不去考虑读者的起点, 结果博客都成了自己给自己看的地方. 报纸杂志都属于通俗易懂的材料, 不需要假定读者的水平如何. 而写书, 则必须要好好考虑读者的水平. 单说算法书, 全世界的算法书加起来也得有个上千本, 但是能称为经典的屈指可数, 而经典书的作者在写书时必然仔细考虑了所面向的读者, 读者的水平和读者所处的上下文. 国人常说, 只可意会不可言传, 我觉得这是表达能力不足的借口. 书的目的便是要省去或起码减少 "悟" 所需要的时间. 我读这道题时最大的感受是作者东一句话西一句话, 以自己的思路和上下文在写书. 需要我花大量的时间去悟. 花了半小时, 知道一段话的意思, 恍然大悟原来如此 --- I hate that. 黑书内容虽好, 写的太差

思路:

1. dp[i] 表示从第 i 个任务开始, 到最后一个任务结束所需的最小总代价

2. dp[i] = min{ dp[j] +w(i,j)}, j > i} w(i, j) = (S + sumT(i) - sumT(j)) * sumF(i)

状态转移方程表示求解 dp[i] 的最优解时, 枚举在 j 处切一刀的所有情况, 即 {i,j之间的任务}U{dp[j]的最优解}, 选取最优的 j

另外, w(i, j) = (S + sumT(i) - sumT(j)) * sumF(i) 这个式子的右端乘上的是 sumF(i) 而不是 sumF(i)-sumF(j), 这是因为预先把 dp[j] 的代价计算了, 这样, "在状态转移方程时就可以每次看作从时间 0 开始工作了", 就不需考虑 dp[i] 是什么时候完成的任务了

比如在给定的测试用例中

5个任务的划分为5个组, 每组一个任务

组1 : 完成时间 0+1+1=2,    代价 3, 耗费 2 * 3 = 6

组2 : 完成时间 +1+3=6,    代价 2, 耗费 6 * 3 = 18

组3 : 完成时间 +1+4=11,  代价 3, 总耗费 11 * 3 = 33

组4 : 完成时间 +1+2=14, 代价 3, 总耗费 14 * 3 = 42

组5 : 完成时间 +1+1=16, 代价 4, 总耗费 16 * 4 = 64

假定 {1,2} {3,4,5} 分成两组, 前两组的完成时间为 6, 在3,4,5组减去(S + sumT(i) - sumT(j)) * sumF(i), 相当于

6+1+4 ---> 0+1+4

11+1+2--->5+1+2

14+1+1--->11+1+1

从 3 的视角来看, 组3似乎是从时间 0 开始计算的

3. 从 (2) 知, 是倒推的过程

总结:

1. 顺序切割的动态规划解法

2. 计算 w[i,j] 的时候, 需要非常小心

代码:

没看懂优化原理, o(n*n) 的 MLE + TLE 代码

#include <iostream>
using namespace std; const int MAXN = 10010;
int N, S;
int t[MAXN], f[MAXN];
int st[MAXN], sf[MAXN];
int w[MAXN][MAXN];
int dp[MAXN]; void pre_process() {
memset(st, 0, sizeof(st));
memset(sf, 0, sizeof(sf));
for(int i = N; i > 0 ; i --) {
st[i] = t[i] + st[i+1];
sf[i] = f[i] + sf[i+1];
} memset(w, 0, sizeof(w));
for(int i = 1; i <= N; i ++) {
for(int j = i+1; j <= N; j ++) {
w[i][j] = (S + st[i]-st[j])*sf[i];
}
} memset(dp, 0, sizeof(dp));
for(int i = N; i > 0; i --) {
dp[i] = (S+st[i])*sf[i];
} }
int mainFunc() { for(int i = N-1; i > 0; i --) {
for(int j = i+1; j <= N; j ++) {
dp[i] = min(dp[i], dp[j]+w[i][j]);
}
}
return dp[1];
}
int main() {
//freopen("E:\\Copy\\ACM\\poj\\1180\\in.txt", "r", stdin);
while(cin >> N >> S) {
for(int i = 1; i <= N; i ++) {
scanf("%d%d", &t[i], &f[i]);
}
pre_process();
// mainFunc
cout << mainFunc() << endl;
}
return 0;
}

  

POJ 1180 Batch Scheduling的更多相关文章

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

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

  2. POJ 1180 - Batch Scheduling - [斜率DP]

    题目链接:http://poj.org/problem?id=1180 Description There is a sequence of N jobs to be processed on one ...

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

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

  4. POJ 1180 Batch Scheduling (dp,双端队列)

    #include <iostream> using namespace std; + ; int S, N; int T[MAX_N], F[MAX_N]; int sum_F[MAX_N ...

  5. poj 1180:Batch Scheduling【斜率优化dp】

    我会斜率优化了!这篇讲的超级棒https://blog.csdn.net/shiyongyang/article/details/78299894?readlog 首先列个n方递推,设sf是f的前缀和 ...

  6. [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 ...

  7. POJ 1180 斜率优化DP(单调队列)

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

  8. 任务调度分配题两道 POJ 1973 POJ 1180(斜率优化复习)

    POJ 1973 这道题以前做过的.今儿重做一次.由于每个程序员要么做A,要么做B,可以联想到0/1背包(谢谢N巨).这样,可以设状态 dp[i][j]为i个程序员做j个A项目同时,最多可做多少个B项 ...

  9. POJ1180 Batch Scheduling 解题报告(斜率优化)

    题目链接:http://poj.org/problem?id=1180 题目描述: There is a sequence of N jobs to be processed on one machi ...

随机推荐

  1. js switch的使用 ng-switch的使用方法

    语法 switch(n) { case 1: 执行代码块 1 break; case 2: 执行代码块 2 break; default: n 与 case 1 和 case 2 不同时执行的代码 } ...

  2. WSAAsyncSelect 模型

    WSAAsyncSelect模型是winsock编程模型的一种,它提供了socket异步编程的方便,其实现是基于Windows消息机制的,最主要的就是下面这个函数: int PASCAL FAR WS ...

  3. 【转】MySQL索引原理及慢查询优化

    MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓“好马配好鞍”,如何能够更好的使用它,已经成为开发工程师的必修课,我们经常会从职位 ...

  4. django 线上线下使用不同的数据库 上线:mysql 线下sqlite3 以及debug模式的开和关

    hostname = socket.gethostname() 获取主机名称 import os import socket hostname = socket.gethostname() if ho ...

  5. 【WPF/WAF】主界面(ShellWindow)引入别的界面布局

    问题:主界面如果只用一个布局文件ShellWindow.xaml,会写得很大很臃肿.需要分为多个布局文件,然后由主界面引入.参考http://waf.codeplex.com/官方的BookLibra ...

  6. git 远程仓库版本的回退以及git reset 几种常用方式记录

    由于 github push 了两个比较潦草的commit, 自己很不满意,又不想重新开vpn进行上传,所以找了一下相关的教程. 最后研究了一下,原理为先在本地还原到你想要的commit,然后强制pu ...

  7. Android——网格视图 GridView

    activity_activitygrid.xml <?xml version="1.0" encoding="utf-8"?> <GridV ...

  8. iOS- 如何将应用集成发短信、发邮件、打电话

    今天把APP里常用小功能 例如发短信.发邮件.打电话. 全部拿出来简单说说它们的实现思路. 1.发短信 实现打电话的功能,主要二种方法,下面我就分别说说它们的优缺点. 1.1.发短信(1)——URL ...

  9. excel导出功能优化

    先说说优化前,怎么做EXCEL导出功能的: 1. 先定义一个VO类,类中的字段按照EXCEL的顺序定义,并且该类只能用于EXCEL导出使用,不能随便修改. 2. 将查询到的结果集循环写入到这个VO类中 ...

  10. [LintCode]各位相加

    描述: 给出一个非负整数 num,反复的将所有位上的数字相加,直到得到一个一位的整数. 给出 num = 38. 相加的过程如下:3 + 8 = 11,1 + 1 = 2.因为 2 只剩下一个数字,所 ...