(45/60)爬楼梯进阶、零钱兑换、完全平方数

day45

爬楼梯进阶

卡码网:爬楼梯(第八期模拟笔试)

动态规划

代码实现

/*
总和为j总共有dp[j]种方法(可重复选取、排列)
dp[j] += dp[j-nums[i]
dp[0] = 1;其余为0
先背包再物品,正序
*/
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int main(){
    int n = 0;  // n阶(总和)
    int m = 0;  // 一次爬1~m阶
    cin>>n; cin>>m;
    vector<int> dp(n+1,0);
    dp[0] = 1;
    // 先背包再物品
    for(int i = 1;i <= n;i++){
        for(int j = 1;j <= m;j++){
            if(i >= j) dp[i] += dp[i - j];
        }
    }
    
    cout<<dp[n];
    
    return 0;
}

零钱兑换

leetcode:322. 零钱兑换

动态规划

注意点

  1. 初始化为INT32_MAX - 1,因为递推判断的时候+1可能会溢出 / 或者dp[j - coins[i]]是初始值则跳过
  2. 求最小硬币数,是排列数、组合数都没关系,遍历先后顺序无所谓

代码实现

class Solution {
public:
/*
可重复
意义:装满容量为j的背包,最小硬币数为dp[j]
递推:dp[j] = min(dp[j - coins[i]],dp[j]);
初始化:dp[0] = 0; 其余为INT32_MAX;
遍历:遍历先后无所谓,可重复要正序
*/
    int coinChange(vector<int>& coins, int amount) {
        vector<int> dp(amount + 1,INT32_MAX - 1 );
        dp[0] = 0;
        for(int i = 0;i < coins.size();i++){
            for(int j = coins[i];j <= amount;j++){
                 if (dp[j - coins[i]] != INT_MAX) { // 如果dp[j - coins[i]]是初始值则跳过
                    dp[j] = min(dp[j - coins[i]] + 1, dp[j]);
                }
            }
        }
        if(dp[amount] == INT32_MAX - 1) return -1;
        return dp[amount];
    }
};

TS:

function coinChange(coins: number[], amount: number): number {
    const dp:number[] = new Array(amount + 1).fill(Number.MAX_VALUE);
    dp[0] = 0;
    for(let i = 0;i < coins.length;i++){
        for(let j = coins[i];j <= amount;j++){
            if(dp[j - coins[i]] !== Number.MAX_VALUE)
                dp[j] = Math.min(dp[j - coins[i]] + 1,dp[j]);
        }
    }
    if(dp[amount] === Number.MAX_VALUE) return -1;
    return dp[amount];
};

完全平方数

leetcode:

动态规划

代码实现

/*
意义:装满容量为j的背包的最少物品数为dp[j](可重复取)
递推:dp[j] = min(dp[j - nums[i]] + 1,dp[j])
初始化:初始化为MAX
遍历:物品数,排列、组合无所谓;可重复取,正序
*/

class Solution {
public:
    int numSquares(int n) {
        vector<int> dp(n+1,INT32_MAX);
        dp[0] = 0;  // 雪球起点,没有意义但必须要有才能滚起来
        for(int i = 1;i*i <= n;i++){
            for(int j = i*i;j <= n;j++){
                if(dp[j - i*i] != INT32_MAX){
                    dp[j] = min(dp[j - i*i] + 1,dp[j]);
                    // cout<<dp[j]<<" ";
                }
            }
            // cout<<endl;
        }

        if(dp[n] == INT32_MAX) return -1;
        return dp[n];
    }
};

TS:

function numSquares(n: number): number {
    const dp:number[] = new Array(n + 1).fill(Number.MAX_VALUE);
    dp[0] = 0;
    for(let i = 1;i*i <= n;i++){
        for(let j = i*i;j <= n;j++){
            if(dp[j - i*i] !== Number.MAX_VALUE){
                dp[j] = Math.min(dp[j - i*i] + 1,dp[j]);
            }
        }
    }

    if(dp[n] === Number.MAX_VALUE) return -1;
    else return dp[n];
};
posted @ 2024-03-21 23:47  Tazdingo  阅读(52)  评论(0)    收藏  举报