题干
硬币。给定数量不限的硬币,币值为25分、10分、5分和1分,编写代码计算n分有几种表示法。(结果可能会很大,你需要将结果模上1000000007)
示例1:
输入: n = 5
输出:2
解释: 有两种方式可以凑成总金额:
5=5
5=1+1+1+1+1
示例2:
输入: n = 10
输出:4
解释: 有四种方式可以凑成总金额:
10=10
10=5+5
10=5+1+1+1+1+1
10=1+1+1+1+1+1+1+1+1+1
说明:
注意:
你可以假设:
0 <= n (总金额) <= 1000000
想法
背包问题:
也就是说每一个单个元素都可以使用无数次
使用动态规划的想法
数组coins{1,5,10,25}
dp[i][j]表示取coins前i个数组成总和为j的方法个数
如果遍历到现在这个coins
如果取了它 那么dp[i][j]=dp[i][j-coins[I]]
如果没有取它
dp[i][j]=dpp[i-1][j];
因为dp表示组合总数
所以把他们加起来
注意边界条件就行
Java代码
package daily;
public class WaysToChange {
public int waysToChange(int n) {
//dp[i][j]表示取coins前i个数组成总和为j的方法个数
int[][] dp=new int[4][n+1];
int []coins={1,5,10,25};
//初始条件 用一个都为1
for(int i=0;i<=n;i++){
dp[0][i]=1;
}
for(int j=0;j<4;j++){
dp[j][0]=1;
}
for (int i=1;i<4;i++){
for (int j=1;j<=n;j++){
//边界条件 必须j比单个面值大才加
if(j>=coins[i]) {
dp[i][j] = (dp[i - 1][j] + dp[i][j - coins[i]])%1000000007;
}
else dp[i][j]=dp[i-1][j];
}
}
return dp[3][n];
}
public static void main(String[] args){
WaysToChange ways=new WaysToChange();
System.out.println(ways.waysToChange(929782));
}
}