换零钱:动态规划
换零钱:动态规划
换零钱有两类问题,分别对应着一维动态规划和二维动态规划
求最少硬币数

它的思路是一维动态规划:dp[i]=1+min(dp[i-k])

dp[i]=1+min(dp[i-k])的1表示选择当前种类的一个硬币,min(dp[i-k])表示要凑齐剩余金额的最少硬币数。通过Min操作,我们找到了使得dp[i-k]最小的k
求换硬币策略数
题目描述
有一个数组changes,changes中所有的值都为正数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,对于一个给定值x,请设计一个高效算法,计算组成这个值的方案数。
给定一个int数组changes,代表所有零钱,同时给定它的大小n,另外给定一个正整数x,请返回组成x的方案数,保证n小于等于100且x小于等于10000。
测试样例:
[5,10,25,1],4,15
返回:6
测试样例:
[5,10,25,1],4,0
返回:1
链接:https://www.nowcoder.com/questionTerminal/185dc37412de446bbfff6bd21e4356ec?f=discussion
来源:牛客网
import java.util.*;
public class Exchange {
public int countWays(int[] changes, int n, int x) {
// write code here
//dp[i][j]表示使用changes[0~i]的钱币组成金额j的方法数
int[][] dp=new int[n][x+1];
//第一列全为1,因为组成0元就只有一种方法
for(int i=0;i<n;i++)
dp[i][0]=1;
//第一行只有changes[0]的整数倍的金额才能有1种方法
for(int j=0;j*changes[0]<=x;j++){
dp[0][j*changes[0]]=1;
}
//从位置(1,1)开始遍历
for(int i=1;i<n;i++){
for(int j=1;j<=x;j++){
//关键:使用0~i的钱币组成j-changes[i]金额的方法数+使用0~i-1钱币组成j的方法数
dp[i][j]=dp[i-1][j]+(j-changes[i]>=0?dp[i][j-changes[i]]:0);
}
}
return dp[n-1][x];
}
}
思路是,用0-i的钱币组成j的策略数=用0-(i-1)的钱币组成j的策略数(也就是不使用第i种钱币的意思)+用0-i的钱币组成j-i的策略数(也就是使用第i个种钱币)
初始化是对第一行和第一列的初始化

浙公网安备 33010602011771号