POJ 1337 A Lazy Worker(区间DP, 背包变形)
Description
We consider a set of jobs 1, 2,..., n having processing times t1, t2,...,tn respectively. Job i arrives at time ai and has its deadline at time di. We assume that ti, ai, and di have nonnegative integral values. The jobs have hard deadlines, meaning that each job i can only be executed during its allowed interval Ii=[ai, di]. The jobs are executed by the worker, and the worker executes only one job at a time. Once a job is begun, it must be completed without interruptions. When a job is completed, another job must begin immediately, if one exists to be executed. Otherwise, the worker is idle and begins executing a job as soon as one arrives. You should note that for each job i, the length of Ii, di - ai, is greater than or equal to ti, but less than 2*ti.
Write a program that finds the minimized total amount of time executed by the worker.
Input
Output
Sample Input
3
3
15 0 25
50 0 90
45 15 70
3
15 5 20
15 25 40
15 45 60
5
3 3 6
3 6 10
3 14 19
6 7 16
4 4 11
Sample Output
50
45
15
思路:
1. 搜索
2. DP. dp[i] 表示从时间 i 到 endtime 之间工作的最小值
dp[i] = min(dp[i+t[j]]+t[j]), t[j] 表示第 j 个任务的执行时间
3. 由(2) 的状态转移方程看, 需要计算在时刻 t 都有哪些任务可做, 时间复杂度 o(m*n) m 是 endtime, n 是 工作数, 且根据题意, endtime < 250, n < 100
总结:
1. 按照思路 (2) 的状态转移方程来做的话, 需要防止一个任务被重复计算两次. 一个直接的应对方法是再加一维, 那一维可通过状态压缩的方法表示那些任务已经被计算过了
2. 这段代码曾忘掉
if(!job[i].size()) { // 没有任务可做
dp[i] = dp[i+1];
continue;
}
代码:
WA 到死
#include <iostream>
#include <vector>
using namespace std;
const int MAXN = 1010;
const int INF = 0X3F3F3F3F;
int t[MAXN], a[MAXN], d[MAXN];
vector<int> job[MAXN];
int n, endTime, startTime;
int dp[MAXN];
int cases;
void pre_process() {
for(int i = 0; i < MAXN; i ++) {
job[i].clear();
} for(int i = startTime; i <= endTime; i ++) {
for(int j = 1; j <= n; j ++) {
if(i >= a[j] && i+t[j] <= d[j])
job[i].push_back(j);
}
} memset(dp, 0x3f, sizeof(dp));
dp[endTime] = 0;
} int mainFunc() { for(int i = endTime-1; i >= startTime; i --) { if(!job[i].size()) { // 没有任务可做
dp[i] = dp[i+1];
continue;
}
dp[i] = INF;
for(int j = 0; j < job[i].size(); j ++) {
int curJob = job[i][j];
int ti = t[curJob];
dp[i] = min(dp[i], dp[i+ti]+ti);
}
}
return dp[startTime];
}
int main() {
freopen("E:\\Copy\\ACM\\poj\\1337\\in.txt", "r", stdin); cin >> cases;
while(cases-- >= 1) {
endTime = 0;
startTime = 1000;
cin >> n;
for(int i = 1; i <= n; i ++) {
scanf("%d%d%d", &t[i], &a[i], &d[i]);
endTime = max(endTime, d[i]);
startTime = min(startTime, a[i]);
}
pre_process();
// mainFunc
cout << mainFunc() << endl;
}
return 0;
}
update 2014年3月15日17:05:31
进行预处理之后, 这道题就变成了常见的朴素 01 背包, 比如 Leetcode wordbreak 什么的
POJ 1337 A Lazy Worker(区间DP, 背包变形)的更多相关文章
- POJ 3280 Cheapest Palindrome(区间DP求改成回文串的最小花费)
题目链接:http://poj.org/problem?id=3280 题目大意:给你一个字符串,你可以删除或者增加任意字符,对应有相应的花费,让你通过这些操作使得字符串变为回文串,求最小花费.解题思 ...
- POJ 3186Treats for the Cows(区间DP)
题目链接:http://poj.org/problem?id=3186 题目大意:给出的一系列的数字,可以看成一个双向队列,每次只能从队首或者队尾出队,第n个出队就拿这个数乘以n,最后将和加起来,求最 ...
- POJ 2955:Brackets(区间DP)
http://poj.org/problem?id=2955 题意:给出一串字符,求括号匹配的数最多是多少. 思路:区间DP. 对于每个枚举的区间边界,如果两边可以配对成括号,那么dp[i][j] = ...
- POJ 1191 棋盘分割(区间DP)题解
题意:中文题面 思路:不知道直接暴力枚举所有情况行不行... 我们可以把答案转化为 所以答案就是求xi2的最小值,那么我们可以直接用区间DP来写.设dp[x1][y1][x2][y2][k]为x1 y ...
- Poj 1651 Multiplication Puzzle(区间dp)
Multiplication Puzzle Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10010 Accepted: ...
- POJ 1651 Multiplication Puzzle (区间DP,经典)
题意: 给出一个序列,共n个正整数,要求将区间[2,n-1]全部删去,只剩下a[1]和a[n],也就是一共需要删除n-2个数字,但是每次只能删除一个数字,且会获得该数字与其旁边两个数字的积的分数,问最 ...
- POJ 1141 Brackets Sequence (区间DP)
Description Let us define a regular brackets sequence in the following way: 1. Empty sequence is a r ...
- poj 2955 Brackets 括号匹配 区间dp
题意:最多有多少括号匹配 思路:区间dp,模板dp,区间合并. 对于a[j]来说: 刚開始的时候,转移方程为dp[i][j]=max(dp[i][j-1],dp[i][k-1]+dp[k][j-1]+ ...
- poj 1390 Blocks (经典区间dp 方块消除)
Blocks Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 4250 Accepted: 1704 Descriptio ...
随机推荐
- java.net.SocketException: Software caused connection abort: socket write erro
场景:接口测试 编辑器:eclipse 版本:Version: 2018-09 (4.9.0) testng版本:TestNG version 6.14.0 执行testng.xml时报错信息: 出现 ...
- 【转】批量删除redis中的key
1. DEL 直接加键名称 DEL key1 key2 key3 127.0.0.1:6379> DEL site_msg_99973 false site_msg_99974 fals ...
- RSA算法工具
RSA算法工具-生成密钥对(生成密钥对) RSA算法工具-解析密钥对(导入密钥对,解析密钥对) RSA测试工具-计算分量(输入P,Q,E,计算出N,DP,DQ,Qinv)
- Java SerialPort SDK
SerialPort SDK is a professional java serial port SDK,provides simple communication interface to con ...
- 常用sqoop操作
1. 关系型数据库到hive sqoop import --connect jdbc:mysql://localhost:3306/datahouse --username datahs --pass ...
- Android中使用SoundPool来播放音频
今天找素材重做FlappyBird时学习了一下怎样为应用设置背景音频,发现通过封装SoundPool类就能够非常好的做到这一点. SoundPool类比較适合播放一些类似游戏音效这样的比較短促并且较小 ...
- iOS开发中的错误整理,导航控制器的导航栏取消系统渲染的错误
- PHP中动态增加属性到对象
参见: <深入PHP 面向对象.模式与实践>(第三版) [ matt zandstra ] - 3.2章节,设置类中的属性(p17)
- font-face自定义字体
做网站的时候,有时候会遇到某些字体系统里面没有自带.可能更多的时候我们会选择以图替文的方式来做.用图片的话不利于图片的放大缩小,更好的办法是我们可以自定义字体. 当然,在实际运用中我们需要权衡一下自定 ...
- C++ 的一个问题的理解(私有变量成员)
class CExample { public: CExample(){pBuffer=NULL; nSize=;} ~CExample(){delete pBuffer;} CExample(con ...