POJ 1337 A Lazy Worker(背包变型题)
题意:
有一位工人, 如果在当前时刻有工作他会执行, 不会休息, 但是他会偷懒, 现在又n个任务, 有执行花费时间t[i], 开始时间a[i], 最后期限d[i];
每一项工作一旦被执行不可以被打断. 现在要求你算出工人最少的工作时间.(如果不满足条件的工作, 丢弃.)
黑书 146 :偷懒的工人
思路:
1. 注意把握住题意:工人们很懒,想尽可能的少干活,但是如果某时刻有活,又必须干;
2. 首先预处理出来时间 t 所能够去做的任务,并且 ti <= di - ai < 2*ti , 这个条件限制的比较巧妙,可以保证了同一个任务不会重复做;
3. dp[t] 表示 t 时间到 endtime 最少的工作时间,所以有:dp[t] = min(dp[t+cost[j]] + cost[j]);
方法一,递推关系式 0ms :
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 110;
const int INFS = 0x3FFFFFFF;
int cost[MAXN], arrival[MAXN], deadline[MAXN];
int N, begtime, endtime, dp[260];
vector<int> G[260];
int main() {
int cases;
scanf("%d", &cases);
while (cases--) {
scanf("%d", &N);
begtime = INFS, endtime = 0;
for (int i = 0; i < N; i++) {
scanf("%d%d%d", &cost[i], &arrival[i], &deadline[i]);
begtime = min(begtime, arrival[i]);
endtime = max(endtime, deadline[i]);
}
for (int i = begtime; i <= endtime; i++) {
G[i].clear();
for (int j = 0; j < N; j++) {
if (arrival[j] <= i && i+cost[j] <= deadline[j])
G[i].push_back(j);
}
}
dp[endtime] = 0;
for (int t = endtime-1; t >= begtime; t--) {
if (!G[t].size()) {
dp[t] = dp[t+1]; continue;
}
dp[t] = INFS;
for (int i = 0; i < G[t].size(); i++) {
int j = G[t][i];
dp[t] = min(dp[t], dp[t+cost[j]] + cost[j]);
}
}
printf("%d\n", dp[begtime]);
}
return 0;
}
方法二,DFS:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 110;
const int INFS = 0x3FFFFFFF;
int cost[MAXN], arrival[MAXN], deadline[MAXN];
int N, begtime, endtime, ans;
vector<int> G[260];
void dfs(int t, int worktime) {
while (t <= endtime && !G[t].size())
++t;
if (t > endtime) {
ans = min(ans, worktime);
return ;
}
for (int i = 0; i < G[t].size(); i++) {
int j = G[t][i];
dfs(t + cost[j], worktime + cost[j]);
}
}
int main() {
int cases;
scanf("%d", &cases);
while (cases--) {
scanf("%d", &N);
begtime = INFS, endtime = 0;
for (int i = 0; i < N; i++) {
scanf("%d%d%d", &cost[i], &arrival[i], &deadline[i]);
begtime = min(begtime, arrival[i]);
endtime = max(endtime, deadline[i]);
}
for (int i = begtime; i <= endtime; i++) {
G[i].clear();
for (int j = 0; j < N; j++) {
if (arrival[j] <= i && i+cost[j] <= deadline[j])
G[i].push_back(j);
}
}
ans = INFS;
dfs(begtime, 0);
printf("%d\n", ans);
}
return 0;
}
-------------------------------------------------------
kedebug
Department of Computer Science and Engineering,
Shanghai Jiao Tong University
E-mail: kedebug0@gmail.com
GitHub: http://github.com/kedebug
-------------------------------------------------------