硬币组成问题

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

硬币组成问题

题目分析

硬币组成问题(Coin Change Problem)是经典的动态规划问题。给定不同面值的硬币和一个目标金额,要求计算出可以组成该金额的不同方式数量。

问题描述

  • 输入:硬币面值数组 coins 和目标金额 amount
  • 输出:组成 amount 的不同组合方式数量。

示例

  • 输入:coins = [1, 2, 5]amount = 5
  • 输出:4 (组合方式:[5], [2, 2, 1], [2, 1, 1, 1], [1, 1, 1, 1, 1])
思路分析
  1. 定义状态

    • 使用数组 dp,其中 dp[i] 表示组成金额 i 的不同组合方式数量。
  2. 初始化

    • dp[0] = 1,表示组成金额0的方式有1种,即不使用任何硬币。
  3. 状态转移方程

    • 对于每种硬币面值 coin,更新 dp 数组:
      dp[j]+=dp[j−coin] dp[j] += dp[j - coin] dp[j]+=dp[jcoin]
    • 其中 jcoinamount 遍历。
  4. 结果

    • 最终 dp[amount] 即为所求。
案例解释

coins = [1, 2, 5]amount = 5 为例,具体步骤如下:

  • 初始化:dp = [1, 0, 0, 0, 0, 0]

  • 使用硬币 1:

    • 更新:dp[1] = dp[1] + dp[0]dp = [1, 1, 0, 0, 0, 0]
    • 更新:dp[2] = dp[2] + dp[1]dp = [1, 1, 1, 0, 0, 0]
    • 更新:dp[3] = dp[3] + dp[2]dp = [1, 1, 1, 1, 0, 0]
    • 更新:dp[4] = dp[4] + dp[3]dp = [1, 1, 1, 1, 1, 0]
    • 更新:dp[5] = dp[5] + dp[4]dp = [1, 1, 1, 1, 1, 1]
  • 使用硬币 2:

    • 更新:dp[2] = dp[2] + dp[0]dp = [1, 1, 2, 1, 1, 1]
    • 更新:dp[3] = dp[3] + dp[1]dp = [1, 1, 2, 2, 1, 1]
    • 更新:dp[4] = dp[4] + dp[2]dp = [1, 1, 2, 2, 3, 1]
    • 更新:dp[5] = dp[5] + dp[3]dp = [1, 1, 2, 2, 3, 3]
  • 使用硬币 5:

    • 更新:dp[5] = dp[5] + dp[0]dp = [1, 1, 2, 2, 3, 4]

最终,dp[5] = 4,表示组成金额5的方式有4种。

代码实现

python代码

import os
import sys

def init_arr(size):
    arr = [0] * size
    arr[0] = 1
    return arr

def solve(coins,n,m,dp):
    for i in range(n):
        for j in range(coins[i],m+1):
              dp[j] += dp[j-coins[i]]

n,m = map(int,input().split())
arr = list(map(int,input().split()))

dp = init_arr(m+1)
if n==0 or m==0: #这道题太坑了呀,硬币数和总额有一个是0就是0,说实话应该是1
  print(0)
else:
  solve(arr,n,m,dp)
  print(dp[m])

C++代码

#include<bits/stdc++.h>
using namespace std;

int solve(int*,int,int,int*);

int main(){
	int n,m;
	cin>>n>>m;
	int* coins = new int(n);
	for(int i=0;i<n;i++){
		cin>>coins[i];
	}
	int* dp = new int(m+1);
	fill(dp,dp+m+1,0);
	dp[0] = 1;
	int res = solve(coins,n,m,dp);
	cout<<res;
	return 0;
}

int solve(int* coins,int n,int m,int* dp){
	for(int i=0;i<n;i++){
		for(int j=*(coins+i);j<=m;j++){
			*(dp+j) += *(dp+j-*(coins+i));
		}
	}
	print_arr(dp,m+1);
	if (n==0 or m==0){
		return 0;
	}	
	else{
		return *(dp+m);
	}
}
总结

硬币组成问题是一个典型的动态规划问题,关键在于定义状态、初始化和状态转移。通过对不同硬币的使用情况进行遍历,可以有效地计算出组成目标金额的不同方式。

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SweetCode

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

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

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

打赏作者

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

抵扣说明:

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

余额充值