zoukankan      html  css  js  c++  java
  • POJ 1337 A Lazy Worker(区间DP, 背包变形)

    Description

    There is a worker who may lack the motivation to perform at his peak level of efficiency because he is lazy. He wants to minimize the amount of work he does (he is Lazy, but he is subject to a constraint that he must be busy when there is work that he can do.) 

    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

    The input consists of T test cases. The number of test cases (T ) is given in the first line of the input file. The number of jobs (0<=n<=100) is given in the first line of each test case, and the following n lines have each job's processing time(1<=ti<=20),arrival time(0<=ai<=250), and deadline time (1<=di<=250) as three integers.

    Output

    Print exactly one line for each test case. The output should contain the total amount of time spent working by the worker.

    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 什么的

  • 相关阅读:
    刨析Maven(对pom.xml配置文件常用标签的解析)
    sublime text 3 使用技巧
    CSS3之渐变
    CSS3之过渡
    定位
    Java中的正则表达式
    CSS3之转换
    CSS布局
    导航条菜单制作总结
    Transition
  • 原文地址:https://www.cnblogs.com/xinsheng/p/3451629.html
Copyright © 2011-2022 走看看