算法导论之贪心算法:活动选择问题

问题描述

每个活动都共享同一个公共的资源(比如教室等)所以同一时间只能有一个活动。现在的问题就是要在指定的时间内让举办的活动数量做大。

这是一个典型的贪心算法。我们不在这里证明算法的正确性。

我们给出贪心算法的定义:它在每一步都作出当时看起来最佳的选择。(它总是做出局部最优的选择,寄希望这样的选择能导致全局最优解)

一般的贪心算法有以下的步骤

1.确定问题的最优子结构。

2.设计一个递归算法。

3.证明如果我们做出一个贪心选择,则只剩下一个子问题。

4.证明贪心选择总是安全的。(步骤3、4的顺序可以调换)

5.设计一个递归算法实现贪心策略。

6.将递归算法转换为迭代算法。

代码实现如下:

#include <stdio.h>

struct Activty{
	int start;
	int finish; 
};
typedef struct Activty Activty;

struct List{
	Activty *value;
	struct List *next; 
};
typedef struct List List;

//迭代贪心算法 
List *GREEDY_ACTIVITY_SELECTOR(Activty action[],int n){
	List *rs = (List *)malloc(sizeof(List));
	rs->value=action;
	List *position = rs;
	int k=0,m=1;
	for(;m<n;m++){
		if(action[m].start>=action[k].finish){
			List *temp = (List *)malloc(sizeof(List));
			temp->value=&action[m];
			position->next=temp;
			position=temp;
			k=m;
		}
	}
	position->next=NULL;
	return rs;
}

//递归贪心算法 
List *RECURSIVE_SELECTOR(Activty action[],int k,int n){
	int m = k+1;
	while(m<n && action[m].start<action[k].finish){
		m++;
	}
	if(m<n){
		List *rs = (List *)malloc(sizeof(List));
		rs->value=&action[m];
		rs->next=RECURSIVE_SELECTOR(action,m,n);
		return rs;
	}else
		return NULL;
}
int main(int argc, char *argv[])
{
	int n = 11;
	Activty action[n];
	//下面是测试数据
	action[0].start=1;action[0].finish=4;
	action[1].start=3;action[1].finish=5;
	action[2].start=0;action[2].finish=6;
	action[3].start=5;action[3].finish=7;
	action[4].start=3;action[4].finish=9;
	action[5].start=5;action[5].finish=9;
	action[6].start=6;action[6].finish=10;
	action[7].start=8;action[7].finish=11;
	action[8].start=8;action[8].finish=12;
	action[9].start=2;action[9].finish=14;
	action[10].start=12;action[10].finish=16;
	List *rs = (List *)malloc(sizeof(List));
	rs->value=&action[0];
	rs->next= RECURSIVE_SELECTOR(action,0,n);
	
	List *temp = rs;
	printf("the follow is RECURSIVE_SELECTOR.\n");
	while(temp!=NULL){
		printf("%d,%d\n",temp->value->start,temp->value->finish);
		temp=temp->next;
	}
	
	List *rs_GREEDY=GREEDY_ACTIVITY_SELECTOR(action,n);
	temp = rs_GREEDY;
	printf("\nthe follow is GREEDY_ACTIVITY_SELECTOR.\n");
	while(temp!=NULL){
		printf("%d,%d\n",temp->value->start,temp->value->finish);
		temp=temp->next;
	}
	return 0;
}

在上述代码中,实现了递归方式的贪心算法和迭代方式的贪心算法,两者的时间复杂度都是O(n)。

参考资料
算法导论

备注
转载请注明出处:http://blog.csdn.net/wsyw126/article/details/51439202
作者:WSYW126

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值