算法-完全背包硬币组合问题

1. 硬币组合问题

给定硬币的面值数组,以及需要找零的目标值 target,输出能满足要求的最小硬币数量。

例如: coins = [1, 2, 5], amount = 12

可使用 2个 面值为5 的硬币和 1个面值为2的硬币满足要求,返回 3。

2. 解法

完全背包问题,面值相同的硬币可以复用,使用动态规划法。

每趟使用一个硬币面值更新数组,数组最后一个元素值即为解
dp[0]:0 dp[1]:1 dp[2]:2 dp[3]:3 dp[4]:4 dp[5]:5 dp[6]:6 dp[7]:7 dp[8]:8 dp[9]:9 
dp[0]:0 dp[1]:1 dp[2]:1 dp[3]:2 dp[4]:2 dp[5]:3 dp[6]:3 dp[7]:4 dp[8]:4 dp[9]:5 
dp[0]:0 dp[1]:1 dp[2]:1 dp[3]:2 dp[4]:2 dp[5]:1 dp[6]:2 dp[7]:2 dp[8]:3 dp[9]:3 
public int coinChange(int[] coins, int target) {
    // coins = [1, 2, 5], target = 9
    if (null == coins || coins.length == 0 || target <=0) return 0;
    int[] dp= new int[target + 1]; // 动态规划数组
    for (int i = 0; i < coins.length ; i++) {
		int coin = coins[i];
		for (int j = coin; j <= target; j++) {
		// 这是一个完全背包问题。完全背包需要将 0-1 背包中逆序遍历 target 改为正序遍历
			if (j = coin) {
				dp[j] = 1;
			} else if (dp[j] == 0 && dp[j - coin] != 0 ) {
				dp[j] = dp[j - coin] + 1;
			} else if (dp[j - coin] != 0){
				dp[j] = Math.min(dp[j], dp[j-coin] + 1 );
			}
		}
	}
	return dp[target] == 0 ? -1 : dp[target];
}

你可能感兴趣的:(算法,动态规划,数组)