【贪心算法】硬币阶乘(最少硬币数)

9 篇文章 1 订阅
2 篇文章 0 订阅

了解阶乘

阶乘其实就是“!”,举个例子:1!=1,2!=1×2,3!=1×2×3
综上所述,n阶乘就是1到n全部正整数相乘的乘积
我们可以用许多方法来实现——1、递归,2、for,3、while,4、打表

也就是说,无论怎样,我们都要初始化这个部分

递归方法:
C++

long long int jc[10004];
void dg(long long int n){
	if(n==1) return 1;
	else return n*dg(n-1);
}
int main(){
	const long long int x=12;
	for(int i=1;i<=x;i++) jc[i-1]=dg(n);
	//for(int i=0;i<x;i++) cout<<jc[i];
	return 0;
}

Python

def dg(n):
	if n == 1:
		return 1
	else:
		return (n*dg(n-1))
jc = []
for i in range(12):
	jc.append(dg(i))
'''
for i in range(1,13):
	print(jc[i],end=" ")
'''

JavaScript

var a = []
function dg(n){
	if(n==1) return 1
	else return n*dg(n-1)
}
for(var i=1;i<13;i++) a.push(dg(i))
// for(var i=0;i<12;i++) alert(a[i])

for的大法:
第一种,谁都能想出来
C++

void initialization(){
	for(int i=0;i<10;i++){
		int t=1;
		for(int j=2;j<=i+1;j++) t*=j;
		coins[i]=t;
	}
}

Python

def initialization(){
	for i in range(10):
		t = 1
		for j in range(1,i+2):
			t*=j
		coins.append(t)
}

JavaScript

function initialization(){
	for(var i=0;i<10;i++){
		var t=1
		for(var j=1;j<=i+1;j++) t*=j
		coins.push(t)
	}
}

第二种,方便时间不超限
C++

void initialization(){
	coins[0]=1
	for(int i=1;i<=10;i++){
		int t=i+1;
		coins[i]=coins[i-1]*t;
	}
}

Python

def initialization():
	coins.append(1)
	for i in range(2,12):
		coins.append(coins[i-2]*i)

JavaScript

function initialization(){
	coins.push(1)
	for(var i=1;i<10;i++){
		var t=i+1
		coins.push(coins[i-1]*t)
	}
}

阶乘方法学完了,接下来是思路和题目

样例题目

X国使用的硬币有1!元硬币、2!元硬币、……10!和元硬币。小明每种硬币都有100枚,他打算通过给出确切的数量而不收零钱来购买价值P元的产品。我们可以证明总有这样一种支付方式,那他在付款中至少需要使用多少硬币?

输入输出格式

输入
P的值

输出
输出所需的最少硬币数。

样例输入输出

输入
119

输出
10

数据范围

1<=P<=10000000 P为整数

思路

  • 1、需要用到前面的阶乘方法
  • 2、本题可以用贪心做
  • 首先可以先从大到小排好序(阶乘)
  • 然后如果P>=coins[i] 就取
  • 用ans来取方案数
  • 看到了题目要求的 “打算通过给出确切的数量而不收零钱来购买”也可以用贪心算法来解决,因为“那他在付款中至少需要多少硬币
  • 输出解决
  • 3、一开始得初始化coins 数组(列表),然后进行倒序取值
  • 4、每次取硬币必须取所能达到最大的
  • 5、所有的硬币都小于min(coins) 的话(可以用flag 布尔值来判断),直接ans+1就行了

代码

C++

#include<bits/stdc++.h>
#define N 10
using namespace std;
int coins[10];
void content(){
	for(int i=0;i<10;i++){
		int t=1;
		for(int j=2;j<=i+1;j++) t*=j;
		coins[i]=t;
	}
}
int main(){
	long long int x,ans=0;
	cin>>x;
	content();
//	for(int i=0;i<N;i++) cout<<coins[i]<<endl; 
	while (x){
		bool flag=false;
		for(int i=N-1;i>0;i--){
			if(x>=coins[i]){
				x-=coins[i];
				ans++;
				flag=true;
				break;
			}
		}
		if(!flag){
			ans++;
			break;
		}
	}
	cout<<ans;
	return 0;
} 

Python

coins = []
ans = 0
def content():
   global coins
   coins.append(1)
   for i in range(1,11):
       coins.append(coins[i-1]*(i+1))

content()
coins.sort(reverse=True)
p = int(input())
while p:
   flag = False
   for i in range(11):
       if p >= coins[i]:
           p-=coins[i]
           ans += 1
           flag = True
           break
   if not flag:
       ans += 1
       break
print(ans)

Javascript

// 这个JS,跟Python和C++都有点相似,可以自己转

我有些不会
看到这里了,能不能点个赞 😉😃😃??

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值