贪心法解币值统计问题

问题描述

币值统计问题:已知各种币值(如100、70、50、20、10、5、2、1),对于给定的整数(比如140),确定每种币值的张数,使得所需的总张数最少。

算法分析

  1. 算法思想:首先对给定的币值进行降序排列,保证每次选择的币值都是最大的,使最终所需要的总张数最小。从面额最大的币种开始遍历,使用贪心算法的思路,对于每个币值,都尽可能多地选取,直到不能够被凑出目标金额为止。其次初始化一个数组count[ ]用来记录每种币值的张数。最后初始化变量num,用于记录所需要的总张数,即为所求解。另外,如果目标金额可以被凑出,则结束程序,否则再次输入币值种类进行分配,这也是贪心算法的局限所在。
  2. 算法实现:设计两个数组,其中,moneylist[ ]用来存放给定的面额种类,count[ ]用来存放每种币值需要的张数。
  3. 时间复杂度:进行币值从大到小排序时,使用选择排序的方法。外层的for循环进行n次,内层的for循环进行\frac{n(n-1)}{2}次,故时间复杂度为T(n)=O(n^{2})

完整代码

#include <iostream>
using namespace std;

int num=0;//总张数 
void alloc(int x){//币值分配 
	cout<<"请输入币值的种类数:";
	int n;
	int moneylist[n]={};//币值种类 
	cin>>n;
	int count[n]={0};//张数 
	cout<<"请输入"<<n<<"种面值:";
	for(int i=0;i<n;i++){
		cin>>moneylist[i];
	}
	
	for(int i=0;i<n;i++){//币值由大到小排序 
		for(int j=i+1;j<n;j++){
			if(moneylist[i]<moneylist[j]){//前一个元素小于后一个元素
				int temp;
				temp=moneylist[i];
				moneylist[i]=moneylist[j];//大的元素向前移动 
				moneylist[j]=temp; 
			}
		}
	}
	
	int temp=0;//临时存储
	for(int i=0;i<n;i++){//分配币值 
		temp=x/moneylist[i];
		count[i]+=temp;
		x=x-moneylist[i]*temp;
		num+=temp; 
		cout<<moneylist[i]<<"元的有"<<count[i]<<"张"<<endl;
	}
	
	if(x==0){//判断是否可以完全分配
		cout<<"目标金额可被完全分配!"<<endl;
		cout<<"所需要的总张数为:"<<num<<endl;
	} 
	else{
		cout<<"目标金额分配不完全,请重新输入目标金额及币值种类!"<<endl;
		cout<<endl;
		cout<<"请输入目标金额(整数):";
		cin>>x;
		alloc(x);
	}

	//cout<<"所需要的总张数为:"<<num<<endl;
} 

int main(){
	int n;
	cout<<"请输入目标金额(整数):";
	cin>>n;
	alloc(n);
	return 0;
}

886! 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Issme

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值