C++课程总结————贪心算法

本文总结了C++中的贪心算法,通过一个实例——删数问题来阐述贪心策略。该问题要求从高精度正整数中删除s个数字,使得剩余数字组成的数最小。传统方法可能误选较大数字删除,但贪心算法考虑(位数大,数字大)的顺序,例如在数字15639中删除2个数字,最优方案是删除6和5,得到最小的139。文章介绍了问题的解决步骤,包括输入、核心算法以及处理前导零的细节,强调贪心算法需全面思考,避免无效操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

贪心定义:

简单来说,贪心就是在所有方法中找到最优秀的方法;

例题:删数问题
  • 一个高精度的正整数,去掉其中s个数后剩下的数按次序将数字组成的新数最小。
  • 这个题要求删掉几个数,然后最小,很多人一定首先想到’sort’,然后挑大的数删。
  • 但贪心往往就会因为考虑不周到而错的,有可能最优并没有考虑的,还有可能只过了样例但过不了特殊数据。像这一题,最优的方案应该是:满足(1.位数大2.数字大)这两个要求。
  • 例如
  • 15639;
    2;

    如果删最大数就变为了153;(先删9再删6)
    但如果用后面的思路就变为了139;(先删6再删5)
    153>139(后面是最优方案)
  • 总结一下,首先输入字符串(这题要用到高精度)输入s——删掉的个数,把字符串储存到a整型数组里;
  • 接着循环s遍——如果删够了就停止了;里面也是一重循环枚举1到n——为了找到特殊情况;
  • 判断特殊情况——两个位数较高的数,且前一个数大于后一个数,就删掉前一个数;
  • 从头开始枚举新的数组,重复上一步;
  • 最后要注意一点,一直不过可能就卡在这里了——前导零!!!
  • 大体懂了思路,开始码代码
    (一)输入
	cin>>s1;
	n=s1.size();
	for(int i=0;i<=n;i++)//字符串从零开始
	{
		a[i+1]=s1[i]-'0';
	}//字符串转数组的过程
	//思想——s1[i]的ASCLL码减去'0'的ASCLL就是s1[i]的整型。
	

(二)核心代码

int m=n;
	for(int i=1;i<=s;i++){//删去s个数
		for(int j=1;j<=n;j++){//枚举每一个数
			if(a[j]>a[j+1])//判断特殊情况
			{
				for(int l=j;l<=n-1;l++){//数组整体向前移动一位,删数
					a[l]=a[l+1];
				}
				break;//从头再枚举一遍新的数组,重复删数
			}
		}
		m--;//记录新的数组长度
	}

(三)删除前导零

bool sub=0;
	for(int i=1;i<=m;i++){
		if(a[i]==0)
  		{
  			sub=0;//清零
			for(int j=i-1;j>=0;j--){//从这个找到的零往前枚举判断
									//是否为前导零
				if(a[j]!=0&&a[j]!=-1) sub=1;
			}
			if(sub==0) a[i]=-1;//标记前导零
		}
	}
	for(int i=1;i<=m;i++){
		if(a[i]!=-1) cout<<a[i];//输出
	}
  • 以上为本题的解法,通过这题,我明白了贪心需要考虑周全,否则就是在做无用功。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值