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;
}
posted @ 2013-04-06 20:10  kedebug  阅读(317)  评论(0编辑  收藏  举报