swustoj1189找零钱

题目:
现在假设你是个店员,为了方便/准确/最优的找零钱,你设计了一个程序.该程序应该实现如下功能: 第一行输入客户所给你金额 第二行输入客户消费的总金额 第三行输出应找的总零钱是多少 第四行输出各种面额的张数(总金额之和要与第三行的数相等,并且要求货币总张数是最少的方案输出) 注:为了简单,假设上述中的金额都是整数,现规定金额的面值为100,50,20,10,5,1元.并且假定客户的金额总是大于所需支付的总金额. 数据类型有int整数表示.

输入:
多组数据,
第一行输入一个整数(表示客户所付的金额),如100
第二行输入一个整数(表示商品的总计金额),如25

输出:
第一行输出 应找的零钱,如75
第二行输出 金额面值1张数1+金额面值2+张数2+…+金额面值N张数N=零钱数。(面值较大的零钱优先排在前面,如50元比20元大,应排在前面)

样例:
输入:
100
25
95
2
输出:
75
501+201+51=75
93
50
1+202+13=93

思路:问了一圈大佬们的思路都是贪婪,就我一个蒟蒻第一反应是dp,然后写了dp的方法,遇到了自己不能解决的bug(我好菜。下面会贴出dp的错误(划重点)代码,原因是因为每张钱只用了一次,大佬给我讲这个要用完全背包做,但我太菜了还没学会,学会再来补代码吧。贪婪的思路就很简单啦。

错误的dp做法:

#include<iostream>
#define minn 1e5
using namespace std;

int pay;//付的钱
int back;//找的钱

struct node{
	int x;//面值
	int y;//数量 
}money[6]={100,0,50,0,20,0,10,0,5,0,1,0};

int dp[100001];//最少的数量 
 
int main(){
	while(cin>>pay>>back){
		int sum=pay-back;
		cout<<sum<<endl;
		dp[0]=0;
		for(int i=1;i<=sum;++i){
			dp[i]=minn;
		}
		for(int i=0;i<6;++i){
			for(int j=sum;j>=money[i].x;--j){
				dp[j]=min(dp[j],dp[j-money[i].x]+1);
				if(dp[j]==(dp[j-money[i].x]+1)){
					money[i].y++;
				}
			}
		}
		for(int i=0;i<=sum;++i){
			cout<<dp[i]<<endl;
		}
	}
	return 0;
} 

正确的贪婪做法:

#include<iostream>
using namespace std;

int pay,back;
int arr[6]={100,50,20,10,5,1};
int count[6];

int main(){
	while(cin>>pay>>back){
		int first=0;
		int sum=pay-back;
		cout<<sum<<endl;
		for(int i=0;i<6;++i){
			count[i]=sum/arr[i];
			sum=sum%arr[i];
		}
		for(int i=0;i<6;++i){
			if(count[i]!=0&&first==0){
				first=1;
				cout<<arr[i]<<"*"<<count[i];
			}else if(count[i]!=0){
				cout<<"+"<<arr[i]<<"*"<<count[i];
			}
		}
		cout<<"="<<(pay-back);
		cout<<endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值