首页 > 代码库 > 活动安排问题
活动安排问题
此题是算法导论贪心算法的16.1-5题。
问题描述:
考虑一个活动选择问题的一个变形:每个活动ai除了开始和结束时间外,还有一个值vi。目标不再是求规模最大的兼容活动子集,而是求值之和最大的兼容活动子集。也就是说,选择一个兼容活动子集A,是的vk(k属于A)之和最大化。设计一个多项式时间的算法求解此问题。
思路:
此题是活动安排问题的一个变形。最优化目标不再是最大兼容活动子集,所以不能用常规的活动安排问题的贪心方案。
考虑这样一个问题,我们对与每个活动i,都可以考虑这个活动i是否被加入到最优活动子集中。所以opt[i]可以从这两中情况得来。
opt[i] = max(opt[i-1], opt(pre(i)+vi));
上述公式需要建立在活动已排序的基础上。活动按照结束时间升序排序。不选择第i个活动时,opt[i] = opt[i-1]; 选择第i个活动时opt[i] = opt(pre(i) + vi); pre(i)表示i活动开始之前结束的活动。根据这个公式我们可以轻松的写出动态规划的代码。
该方法最坏情况下时间复杂度为O(n^2);最好情况下为O(n);
代码:
#include <iostream> //c++ #include <algorithm> #include <vector> using namespace std; typedef struct activity{ int start; int end; int value; }Activity; bool myfunction (Activity a, Activity b) { return (a.end < b.end); } int getMostProfit(vector<Activity> activities){ if(activities.size() == 0) return 0; sort(activities.begin(), activities.end(),myfunction); int opt[activities.size()]; opt[0] = activities[0].value; for(int i = 1; i < activities.size(); i++){ int j; for(j = i-1; j >=0; j--){ if(activities[j].end <= activities[i].start) break; } if(j >=0) opt[i] = ((opt[i-1]>opt[j]+activities[i].value)?opt[i-1]:(opt[j]+activities[i].value)); else opt[i] = ((opt[i-1]>activities[i].value)?opt[i-1]:activities[i].value); } for(int i = 0; i < activities.size(); i++) cout << opt[i] << endl; return opt[activities.size()-1]; } int main(){ int starts[] = {1,3,0,5,3,5,6,8,8,2,12}; int ends[] ={4,5,6,7,9,9,10,11,12,14,16}; int values[] = {1,2,4,6,4,2,3,3,4,1,3}; vector<Activity> activities; for(int i = 0; i < 11 ; i++){ Activity tmp; tmp.start = starts[i]; tmp.end = ends[i]; tmp.value = http://www.mamicode.com/values[i];>参考:《算法导论》
活动安排问题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。