leetcode【每日一题】面试题 08.11. 硬币 Java

题干

硬币。给定数量不限的硬币,币值为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));
    }
}

我的leetcode代码都已经上传到我的git

你可能感兴趣的:(leetcode刷题)