贪心之不完整例题

1:活动时间安排的问题

       设有N个活动时间集合,每个活动都要使用同一个资源,比如说会议场,而且同一时间内只能有一个活动使用,每个活动都有一个使用活动的开始si和结束时间fi,即他的使用区间为(si,fi),现在要求你分配活动占用时间表,即哪些活动占用该会议室,哪些不占用,使得他们不冲突,要求是尽可能多的使参加的活动最大化,即所占时间区间最大化!

原文:https://blog.csdn.net/effective_coder/article/details/8736718

#include<stdio.h>
#include<string.h>

void GreedyChoose(int len,int s[11],int f[11],int flag[11]);

int main()
{
	int i,book[11];
	int s[11] ={1,3,0,5,3,5,6,8,8,2,12};
	int f[11] ={4,5,6,7,8,9,10,11,12,13,14};
	memset(book,0,sizeof(book));
	GreedyChoose(11,s,f,book);
	for(i = 0; i < 11; i ++)
		if(book[i])
			printf("%d ",i);
	printf("\n");
	return 0;
}
void GreedyChoose(int len,int s[11],int f[11],int flag[11])
{
	int i,j;
	flag[0] = 1;
	j = 0;
	for(i = 1; i < len; i ++)
		if(s[i] > f[j])
		{
			flag[i] = 1;
			j = i;
		}
}

类似这种题还有个区间覆盖问题,就是说很多个区间,其中有些是相互覆盖着的,要求去除多余的区间,使剩下的区间占用长度最大,实际就是这个题,只是问法变换了而已!

2.贪心实例之线段覆盖

在一维空间中告诉你N条线段的起始坐标与终止坐标,要求求出这些线段一共覆盖了多大的长度。

#include<stdio.h>
int main()
{
	int i,j,len;
	int s[10] = {2,3,4,5,6,7,8,9,10,11};
	int f[10] = {3,5,7,6,9,8,12,10,13,15};
	len = f[0]-s[0];
	j = 0;
	for(i = 1; i < 10; i ++)
	{
		if(s[i] >= f[j])
		{
			len += f[i]-s[i];
			j = i;
		}
		else
		{
			if(f[i] <= f[j])
				continue;
			else
			{
				len += f[i]-f[j];
				j = i;
			}
		}
	}
	printf("%d\n",len);
	return 0;
}

运行结果为13.

3:数字组合问题

设有N个正整数,现在需要你设计一个程序,使他们连接在一起成为最大的数字,比如说3个整数 12,456,342 很明显是45634212为最大,4个整数 342,45,7,98显然为98745342最大

程序要求:输入整数N 接下来一行输入N个数字,最后一行输出最大的那个数字!

题目解析:这道题乍一看挺简单,但仔细分析分析也是有点难度的。简单在好像就是寻找哪个开头最大,然后连在一起就是了,难在如果N大了,假如几千几万,好像就不是那么回事了,要解答这个题目需要选对合适的贪心策略,并不是把数字由大排到小那么简单。

相信冒泡排序都已经很熟悉了,注意看程序中最核心的比较规则是什么,是这一句if(a[j] > a[j+1] ) 他是以数字大小作为比较准则来返回true或者是false,那么我们完全可以改变一下这个排序准则,比如23,123,这两个数字,在我们这个题中它可以组成两个数字 23123和12323,分明是前者大些,所以我们可以说23排在123前面,也就是23的优先级比123大,123的优先级比23小,所以不妨写个函数,传递参数a和b,如果ab比ba大,则返回true,反之返回false。

#include<stdio.h>
#include<math.h>
int compare(int num1,int num2);

int main()
{
	int i,j,t,n,a[110];
	scanf("%d",&n);
	for(i = 1; i <= n; i ++)
		scanf("%d",&a[i]);
	for(i = 1; i < n; i ++)
		for(j = 1; j <= n-i; j ++)
			if(compare(a[j],a[j+1]))
			{
				t = a[j];
				a[j] = a[j+1];
				a[j+1] = t;
			}
	for(i = 1; i <= n; i ++)
		printf("%d",a[i]);
	printf("\n");
	return 0;
}
int compare(int num1,int num2)
{
	int i,ans1,ans2,k1,k2;
	k1 = num1;
	k2 = num2;
	ans1 = ans2 = 0;
	while(num1)
	{
		ans1 ++;
		num1 /= 10;
	}
	while(num2)
	{
		ans2 ++;
		num2 /= 10;
	}
	if((k1*pow(10,ans2)+k2) < (k2*pow(10,ans1)+k1))
		return 1;
	return 0;
}

4:找零钱的问题

在贪心算法里面最常见的莫过于找零钱的问题了,题目大意如下,对于人民币的面值有1元 5元 10元 20元 50元 100元,下面要求设计一个程序,输入找零的钱,输出找钱方案中最少张数的方案,比如123元,最少是1张100的,1张20的,3张1元的,一共5张!
解析:这样的题目运用的贪心策略是每次选择最大的钱,如果最后超过了,再选择次大的面值,然后次次大的面值,一直到最后与找的钱相等。

#include<stdio.h>
int main()
{
	int i,j,all,Moneycount,count;
	int MoneyClass[6] = {100,50,20,10,5,1};
	int MoneyIndex[6] ={0};
	Moneycount = count = 0;
	scanf("%d",&all);
	for(i = 0; i < 6;)
	{
		if(Moneycount+MoneyClass[i] > all)
		{
			i ++;
			continue;
		}
		Moneycount += MoneyClass[i];
		MoneyIndex[i] ++;
		count ++;
		if(Moneycount == all)
			break;
	}
	for(i = 0; i < 6; i ++)
		if(MoneyIndex[i] != 0)
			printf("%d =%d\n",MoneyClass[i],MoneyIndex[i]);
			
	printf("%d\n",count);
	return 0;
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值