活动选择问题(贪心算法)。。。。标题一定要长

qeesung 2015-04-27 10:43:32
小弟在看《算法导论》第十六章的时候,看见习题
引用
16.1-3上说在剩余兼容活动中选择持续时间最短者不能得到最大集

于是我就试了一下,发现是可以得到最大集的,但是为什么选择最早结束的活动就一定能得到最大集呢?求解啊!
下面是选择持续时间最短者的实现代码

#include <iostream>
#include <utility>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>

using namespace std;

#define BufSize 20
// 用来存储解决方案
char buf[BufSize];
std::vector<string> solution;

size_t dealGreatActivitySelector(std::vector<pair<int , int> > & activities , int left , int right);
size_t greatActivitySelector(std::vector<pair<int , int> > & activities)
{
if(activities.size() == 0)
return 0;
return dealGreatActivitySelector(activities , 1 , activities.size()-1);
}

//实际递归函数
size_t dealGreatActivitySelector(std::vector<pair<int , int> > & activities , int left , int right)
{
if(left > right)
return 0;
//首先找到消耗最小的那个
int minPos = left;
int min = 100;
for(int i = left ; i < right ; ++i)
{
if((activities[i].second-activities[i].first) < min)
{
min = activities[i].second-activities[i].first;
minPos = i;
}
}
snprintf(buf , BufSize , "a%d" , left);
solution.push_back(string(buf , buf+BufSize));
memset(buf , BufSize , 0);
int leftTemp = minPos;
int rightTemp = minPos;
/** 找到左边界 */
while(leftTemp >= left && activities[leftTemp].second > activities[minPos].first )
leftTemp--;
/** 找到右边界 */
while(rightTemp <= right && activities[rightTemp].first < activities[minPos].second)
rightTemp++;

return dealGreatActivitySelector(activities , left , leftTemp)+\
dealGreatActivitySelector(activities , rightTemp, right)+1;
}

void printSolution()
{
for (std::vector<string>::iterator i = solution.begin(); i != solution.end(); ++i)
{
cout<<*i<<"\t";
}
cout<<endl;
}

int main(int argc, char const *argv[])
{
std::vector<pair<int , int> > activities;
activities.push_back(pair<int , int>(0,0));
activities.push_back(pair<int , int>(1,4));
activities.push_back(pair<int , int>(3,5));
activities.push_back(pair<int , int>(0,6));
activities.push_back(pair<int , int>(5,7));
activities.push_back(pair<int , int>(3,9));
activities.push_back(pair<int , int>(5,9));
activities.push_back(pair<int , int>(6,10));
activities.push_back(pair<int , int>(8,11));
activities.push_back(pair<int , int>(8,12));
activities.push_back(pair<int , int>(2,14));
activities.push_back(pair<int , int>(12,16));
cout<<"The max selectors is : "<<greateActivitySelector(activities)<<endl;
printSolution();
return 0;
}

...全文
422 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
「已注销」 2016-02-04
  • 打赏
  • 举报
回复
选短活动,反例:


    std::vector<pair<int , int> > activities;
activities.push_back(pair<int , int>(0,0));
activities.push_back(pair<int , int>(1,4));
activities.push_back(pair<int , int>(3,5));
activities.push_back(pair<int , int>(4,7));
activities.push_back(pair<int , int>(6,8));
activities.push_back(pair<int , int>(7,10));


选短活动算法得出结果为选活动区间(3,5)和(6,8)
实际最优解为(1,4)(4,7)(7,10)
qeesung 2015-04-27
  • 打赏
  • 举报
回复
补充一点,最大兼容活动子集是{a1,a4,a8,a11}

64,282

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧