zoukankan      html  css  js  c++  java
  • 九度 1499:项目安排(任务调度, 01背包变形)

    题目描述:

    小明每天都在开源社区上做项目,假设每天他都有很多项目可以选,其中每个项目都有一个开始时间和截止时间,假设做完每个项目后,拿到报酬都是不同的。由于小明马上就要硕士毕业了,面临着买房、买车、给女友买各种包包的鸭梨,但是他的钱包却空空如也,他需要足够的money来充实钱包。万能的网友麻烦你来帮帮小明,如何在最短时间内安排自己手中的项目才能保证赚钱最多(注意:做项目的时候,项目不能并行,即两个项目之间不能有时间重叠,但是一个项目刚结束,就可以立即做另一个项目,即项目起止时间点可以重叠)。

    思路

    1. 一道任务调度题, 为此专门翻了下算法导论, 回顾了上面那道贪心可解的调度题目. 那道题目给定任务的起始点, 求解最大的不想交子集. 动态规划的状态转移方程为

    S(i,j) = max(S(i,k), S(k+1, j) ) 其中 S(i,j) 表示任务 i, j 之间的时间段. 贪心解法是按照任务的结束时间排序, 优先选择完成时间早的 

    2. 编程之美上也有两道任务调度题. (1) n 个学生, m 个研究组, 每个学生可以参加自己喜欢的研究组, 如何安排见面会才能使得总时间最短. 解法是转化为图着色问题, 若一个学生同时对多个研究组感兴趣, 那么这些研究组之间各有直线连通, 用最少的色将图着色, 邻接的点颜色不同 (2) 有 N 场见面会要进行, 每一场见面会的起终时间给定, 求解至少需要多少场地才能让这些见面会能够正常进行. 解法是转化为区间图, 使用贪心算法求解, 尽量使用可以使用的, 序号最小的颜色着色

    3. 这道题我本想着按照 (1) 的动规思路求解, 大致写了下状态转移方程, 觉得实现上可能会有难点, 尤其是判断某个区间内有哪些任务的问题, 觉得会很复杂. 取搜了下资料, 看到了两个关键字, 背包. 于是用背包的思路想了下, 写了状态转移方程.

    dp[i] 表示第 i 项任务截止时间前能够获得的最大收益. dp[i] = max(dp[j]) + value[i]. j < i

    o(n*n) 的时间复杂度, AC 了

    4. 我记得以前做 kedebug 上的题目时也遇到过这种题目, 有时间要把任务调度的题目总结下. 记得去年 works application 给了一道笔试题就是任务调度的

    代码

    #include <iostream>
    #include <stdio.h>
    #include <vector>
    #include <memory.h>
    #include <algorithm>
    using namespace std;
    
    class Task {
    public:
        int st, ed, value;
        Task(int _st, int _ed, int _value):st(_st), ed(_ed), value(_value) {
            //cout << st << " " << ed << " " << value << endl;
        }
        Task() {
            Task(0, 0, 0);
        }
        bool operator<(const Task &ths) const {
            return this->ed < ths.ed;
        }
    };
    
    int n;
    int dp[10010];
    vector<Task> tasks;
    
    int main() {
        while(scanf("%d", &n) != EOF) {
            int st, ed, value;
            tasks.clear();
    
            for(int i = 0; i < n; i ++) {
                scanf("%d%d%d", &st, &ed, &value);
                tasks.push_back(Task(st, ed, value));
            }
    
            sort(tasks.begin(), tasks.end());
            memset(dp, 0, sizeof(int)*(n+2));
    
            dp[0] = 0;
            for(int i = 1; i <= n; i ++) {
                int start = tasks[i-1].st;
                dp[i] += tasks[i-1].value;
                int maxval = 0;
                for(int j = 0; j+1 < i; j ++) {
                    if(tasks[j].ed > start) continue;
                    maxval = max(maxval, dp[j+1]);
                }
                dp[i] += maxval;
            }
    
            int res =0;
            for(int i = 1; i <= n; i ++)
                res = max(res, dp[i]);
            printf("%d
    ", res);
        }
    
        return 0;
    }
  • 相关阅读:
    stagefright框架 Video Playback的流程
    ubuntu 10.10 安装 无线网卡驱动
    ffmpeg 播放 m3u8 ts 流时 av_read_frame 流程
    错误:expected classname before ‘{’ token
    avcodec_decode_video2 第三个参数 got_picture_ptr 的含义
    ndk 编译 ffmpeg
    Windows Phone 7中用好Silverlight开发利器
    利用Visual Studio 2010流程模板实现Scrum敏捷开发(下)
    VS2010中使用IntelliTrace来进行调试
    在Windows Azure中实现和调试一个WCF服务(下)
  • 原文地址:https://www.cnblogs.com/xinsheng/p/3585570.html
Copyright © 2011-2022 走看看