POJ 1180 Batch Scheduling
2015-09-08 00:16
459 查看
斜率优化DP
题意:给你N个jobs,要你去用一台或多台机器 顺序 完成,然后每一台机器启动之前需要S的时间去准备;
如果一台机器要完成3个jobs,那么这3个jobs完成的时间就都是 tt =(开始的时间 + S + t[a] + t[b] + t[c]);
所以代价是tt*f[a] + tt * f[b] + tt * f[c];
求完成所有jobs的最少代价
这一到题目的难点就是不知道最优解会用几台机器,前面用了多少台机器会影响后面的状态
所以我们可以试着倒推;
dp[i] 表示完成 i -- n 的jobs所需要的代价;
然后会有
st[i]表示t[i]+t[i+1]+...+t
;
sf[i]表示f[i]+f[i+1]+...+f
;
dp[i] = dp[k] + (s + st[i] - st[k]) * (sf[i] - sf[k]) + (s + st[i] - st[k]) * sf[k]; i<k<=n;
= dp[k] + (s + st[i] - st[k]) * sf[i] ;
接下来就是普通的斜率优化DP了;
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int INF = 1 << 30;
const int N = 10005;
int st
, sf
, q
, t
, f
;
int dp
;
int n,s;
int getdp(int i, int k){
return dp[k] + (s + st[i] - st[k]) * sf[i];
}
int getup(int j, int k){
return dp[j] - dp[k];
}
int getdown(int j, int k){
return st[j] - st[k];
}
int main(){
int head, tail;
while(~scanf("%d%d",&n,&s)){
memset(dp,0,sizeof(dp));
for(int i = 1; i <= n; i++){
scanf("%d%d", t+i, f+i);
}
st[n+1] = sf[n+1] = 0;
for(int i = n; i > 0; i--){
st[i] = st[i+1] + t[i];
sf[i] = sf[i+1] + f[i];
}
head = tail = 0;
q[tail++] = n+1;
for(int i = n; i > 0; i--){
while(head < tail-1 && getup(q[head+1], q[head]) <= sf[i] * getdown(q[head+1], q[head]))
head++;
dp[i] = getdp(i,q[head]);
while(head < tail-1 && getup(q[tail-2], q[tail-1]) * getdown(q[tail-1], i) >= getup(q[tail-1], i) * getdown(q[tail-2], q[tail-1]))
tail--;
q[tail++] = i;
}
printf("%d\n",dp[1]);
}
return 0;
}
题意:给你N个jobs,要你去用一台或多台机器 顺序 完成,然后每一台机器启动之前需要S的时间去准备;
如果一台机器要完成3个jobs,那么这3个jobs完成的时间就都是 tt =(开始的时间 + S + t[a] + t[b] + t[c]);
所以代价是tt*f[a] + tt * f[b] + tt * f[c];
求完成所有jobs的最少代价
这一到题目的难点就是不知道最优解会用几台机器,前面用了多少台机器会影响后面的状态
所以我们可以试着倒推;
dp[i] 表示完成 i -- n 的jobs所需要的代价;
然后会有
st[i]表示t[i]+t[i+1]+...+t
;
sf[i]表示f[i]+f[i+1]+...+f
;
dp[i] = dp[k] + (s + st[i] - st[k]) * (sf[i] - sf[k]) + (s + st[i] - st[k]) * sf[k]; i<k<=n;
= dp[k] + (s + st[i] - st[k]) * sf[i] ;
接下来就是普通的斜率优化DP了;
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int INF = 1 << 30;
const int N = 10005;
int st
, sf
, q
, t
, f
;
int dp
;
int n,s;
int getdp(int i, int k){
return dp[k] + (s + st[i] - st[k]) * sf[i];
}
int getup(int j, int k){
return dp[j] - dp[k];
}
int getdown(int j, int k){
return st[j] - st[k];
}
int main(){
int head, tail;
while(~scanf("%d%d",&n,&s)){
memset(dp,0,sizeof(dp));
for(int i = 1; i <= n; i++){
scanf("%d%d", t+i, f+i);
}
st[n+1] = sf[n+1] = 0;
for(int i = n; i > 0; i--){
st[i] = st[i+1] + t[i];
sf[i] = sf[i+1] + f[i];
}
head = tail = 0;
q[tail++] = n+1;
for(int i = n; i > 0; i--){
while(head < tail-1 && getup(q[head+1], q[head]) <= sf[i] * getdown(q[head+1], q[head]))
head++;
dp[i] = getdp(i,q[head]);
while(head < tail-1 && getup(q[tail-2], q[tail-1]) * getdown(q[tail-1], i) >= getup(q[tail-1], i) * getdown(q[tail-2], q[tail-1]))
tail--;
q[tail++] = i;
}
printf("%d\n",dp[1]);
}
return 0;
}
相关文章推荐
- POJ ACM 1001
- POJ ACM 1002
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- 用单调栈解决最大连续矩形面积问题
- 2632 Crashing Robots的解决方法
- 1573 Robot Motion (简单题)
- POJ 1200 Crazy Search(简单哈希)
- 【高手回避】poj3268,一道很水的dijkstra算法题
- POJ 1088 滑雪
- poj2387 Til the Cows Come Home—Dijkstra模板
- poj 2485 Highways