牛客题解 | 换零钱

题目

题目链接

解题思路

这是一个完全背包问题的变种,求组合数。关键点:

  1. 状态定义

    • \(dp[i]\) 表示组成金额 \(i\) 的方案数
  2. 状态转移

    • \(dp[i] += dp[i - coin]\)
    • 对每个面值 \(coin\),更新所有可能的金额 \(i\)
  3. 边界条件

    • \(dp[0] = 1\),表示金额为 \(0\) 时有 \(1\) 种方案(什么都不选)
    • 金额为负数时方案数为 \(0\)

代码

class Exchange {
public:
    int countWays(vector<int>& changes, int n, int x) {
        vector<int> dp(x + 1, 0);
        dp[0] = 1;  // 初始化,金额为0时有1种方案
        
        // 遍历每种面值
        for(int coin : changes) {
            // 更新所有可能的金额
            for(int i = coin; i <= x; i++) {
                dp[i] += dp[i - coin];
            }
        }
        
        return dp[x];
    }
};
import java.util.*;

public class Exchange {
    public int countWays(int[] changes, int n, int x) {
        int[] dp = new int[x + 1];
        dp[0] = 1;  // 初始化,金额为0时有1种方案
        
        // 遍历每种面值
        for(int coin : changes) {
            // 更新所有可能的金额
            for(int i = coin; i <= x; i++) {
                dp[i] += dp[i - coin];
            }
        }
        
        return dp[x];
    }
}
# -*- coding:utf-8 -*-
class Exchange:
    def countWays(self, changes, n, x):
        dp = [0] * (x + 1)
        dp[0] = 1
        
        for coin in changes:
            for i in xrange(coin, x + 1):
                dp[i] += dp[i - coin]
        
        return dp[x]

算法及复杂度

  • 算法:动态规划(完全背包)
  • 时间复杂度:\(\mathcal{O(nx)}\),其中 \(n\) 为零钱种类数,\(x\) 为目标金额
  • 空间复杂度:\(\mathcal{O(x)}\),需要一个长度为x+1的dp数组
posted @ 2025-03-07 10:33  wangxiaoxiao  阅读(16)  评论(0)    收藏  举报