【动态规划】Order

来源:互联网 发布:html源码怎么用 编辑:程序博客网 时间:2024/04/30 12:06

woj里面遇到的一个动态规划问题,思路参考著名题目尼克的任务


Description
Knuthocean is a coach of WHUACM team now. One day, he wants to have a meeting with the team members, so he should order a classroom
for the meeting. Classrooms in WHU are lacking, so the administrator must accept some orders and refuse the others to optimize
the classroom’s use efficency. If one order is accepted, the time between the start time and the finish time of this order becomes active.
There can be at most one order during each time slice. Because of your capacity in programming, the administator asks you to
find a method to maximize the total active time. Your task is like that:read the orders and calculate the maximal length of the active time.


Input
Standard input will contain multiple test cases. For each test case, the first line is a number N,(N<=10000) followed by N lines.
Each line contains two integers, p and k.(1<=p<=k<=300000), where p is the start time and k is the finish time of an order.


Output
For each test case, you should output one line containing the maximal length of the active time.
Sample Input
4
1 2
3 5
1 4
4 5


Sample Output
5


Hint
Choose the order (1-2) and (3-5) and the length of the active time is 5 and is maximal.


Source
fp@WOJ


题目大意就是任意时间段只能执行一个任务,给出任务的起始时间点和结束时间点(左闭右闭),求最长的工作时间。


思路采用动态规划中的倒推法,假设长度为n,每个时间点i到n+1处工作的最长时间设为f[i],那么有f[n+1]=0。往前推导,对每一个f[i],有两种情况:

  1. 继承f[i+1],即不加入新的工作。
  2. 如果有某个工作(i,j),考虑倒推回f[j+1]的地方再加上这段工作。
    所以f[i]的推导公式为:
f[i] = max(f[i],f[i+t]+t);

最后得到的f[0](f[1])即为所求结果。


代码如下:

////  main.cpp//  1072////  Created by waple on 16/12/20.//  Copyright © 2016年 waple. All rights reserved.//#include <iostream>#include <cstdio>#include <algorithm>#include <vector>using namespace std;int f[300010];   //注意这里应该申明为全局变量,因为全局变量存储在数据段中,函数里的变量申请在堆栈段中,堆栈的存储空间远小于数据段,如果存储空间很大往往会报错。int main(int argc, const char * argv[]) {    int n;    while (scanf("%d",&n)!=EOF) {        vector<int> s[300010];   //使用向量存储工作任务信息        int m = 0;        //init        for (int i = 0; i < n; i++) {            int a,b;            cin >> a >> b;            m = max(m,b);    //m为最大长度            s[a].push_back(b);        }        //cal        f[m+1] = 0;        for (int j = m; j >= 0; j--) {            vector<int>::iterator it;            f[j] = f[j+1];            for (it = s[j].begin(); it != s[j].end(); it++) {                f[j] = max(f[j],f[(*it)+1]+((*it)+1-j));            }        }        printf("%d\n",f[0]);    }    return 0;}

以上。

0 0