算法之旅 直奔贪心

56 篇文章 0 订阅
36 篇文章 1 订阅

活动选择问题

  • 引言

三月份开始了,各种笔试面试接踵而至,淡定淡定呀。。。

  • 题目

给出一组活动,其中每个活动都有一个开始时间和一个结束。给你一个总的时间区间,然后可以容纳的最多的活动组合。(选自算法圣经)

  • 思路

本题目是贪心的例题1,切记贪心的答案不一定是最优的。本题目的解法使用贪心,缩小问题的规模,直至问题规模缩小至不能在缩小为止。

题目解法 递归解法

// function: 递归
void ActivitiesChoices::PECURSIVE_ACTIVITY_SELECTOR( int i ,int n ) 
{
	int m = i + 1 ;
	while( m<=n && s[m]<f[i] )
		m = m+1 ;
	if( m <= n )
	{
		Result->push_front(m) ;
		this->PECURSIVE_ACTIVITY_SELECTOR(m,n) ;
	}
}

非递归解法

// function: 非递归
void  ActivitiesChoices::GREEDY_ACTIVITY_SELECTOR( )
{
	Result->clear();
	Result->push_front(1);
	int i =1 ;
	int m ;
	for( m = 2 ; m <= size ; m++ )
	{
		if( s[m]>=f[i] )
		{
			Result->push_front(m) ;
			i = m ;
		}
	}
}

弊端:没有求出所有的答案,答案不全。

  • 实验

  • 代码

test.cpp
#include <iostream>
#include <list>
#include <fstream>
using namespace std ;

int const size = 11 ;

class ActivitiesChoices
{
	int * s ;
	int * f ;
	list<int> * Result;
public:
	ActivitiesChoices( void ) ;
	void SF_time_read( ) ;
	void SF_time_set( ) ;
	void PECURSIVE_ACTIVITY_SELECTOR( int i ,int n ) ;
	void GREEDY_ACTIVITY_SELECTOR();
	void Result_Show( ) ;
	void Main( ) ;
	~ActivitiesChoices( void ) ;
};


ActivitiesChoices::ActivitiesChoices(void)
{
	s = new int[size+1] ;
	f = new int[size+1] ;
	Result =new list<int>;
}
void ActivitiesChoices::SF_time_set( )
{
	int a[12]={0,1,3,0,5,3,5,6,8,8,2,12};
	int b[12]={0,4,5,6,7,8,9,10,11,12,13,14};
	ofstream fileWriter ;
	fileWriter.open("data.txt") ;
	fileWriter.clear();
	int i = 1 ;

	fileWriter<<'S';
	//fileWriter<<'\n';// 2 个字符
	while( i <= size )
	{
		fileWriter<<a[i];
		fileWriter<<'-';
		i++;
	}
	i = 1;
	fileWriter<<'\n'; // 3 个字符
	fileWriter<<'F';
	//fileWriter<<'\n';
	while(i<=size)
	{
		fileWriter<<b[i]<<'-';
		i++;
	}
	fileWriter.close();
}

void ActivitiesChoices::SF_time_read( )
{
	ifstream fileReader;
	fileReader.open("data.txt");
	int i = 1 ;
	char c ;
	fileReader>>c ;

	//fileReader>>c ;// 2个字符
	cout<<c ;
	while( i<=size )
	{
		fileReader>>s[i]>>c ;
		cout<<s[i]<<' ' ;
		i++ ;
	}
	i = 1 ;
	//fileReader>>c ; // 3 个 字符
	//cout<<c ;
	cout<<endl ;
	fileReader>>c ;
	cout<<c ;

	//fileReader>>c ;
	//cout<<c ;
	while( i <= size )
	{
		fileReader>>f[i]>>c ;
		cout<<f[i]<<' ' ;
		i++ ;
	}
	cout<<endl ;		
	fileReader.close() ;
}

// function: 递归
void ActivitiesChoices::PECURSIVE_ACTIVITY_SELECTOR( int i ,int n ) 
{
	int m = i + 1 ;
	while( m<=n && s[m]<f[i] )
		m = m+1 ;
	if( m <= n )
	{
		Result->push_front(m) ;
		this->PECURSIVE_ACTIVITY_SELECTOR(m,n) ;
	}
}

void ActivitiesChoices::Result_Show()
{
	while(! Result->empty() )
	{
		cout<<Result->back()<<endl ;
		Result->pop_back() ;
	}
}

// function: 非递归
void  ActivitiesChoices::GREEDY_ACTIVITY_SELECTOR( )
{
	Result->clear();
	Result->push_front(1);
	int i =1 ;
	int m ;
	for( m = 2 ; m <= size ; m++ )
	{
		if( s[m]>=f[i] )
		{
			Result->push_front(m) ;
			i = m ;
		}
	}
}

void ActivitiesChoices::Main( )
{
	this -> SF_time_set() ;
	this -> SF_time_read() ;
	this -> PECURSIVE_ACTIVITY_SELECTOR( 0  ,size );
	this -> Result_Show();
	cout<<endl;
	this -> GREEDY_ACTIVITY_SELECTOR();
	this -> Result_Show();
}

ActivitiesChoices::~ActivitiesChoices(void)
{
	delete [] s,f ;
}


int main()
{

	ActivitiesChoices * AC = new ActivitiesChoices();
	AC ->Main();
	delete AC;
	system("pause");
	return 0 ;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值