代码随想录训练营第45天|70.爬楼梯、322.零钱兑换、279.完全平方数

70.爬楼梯322.零钱兑换279.完全平方数

70.爬楼梯

这是当初做过的一道题,当初是直接用动态规划做的,此时也可以用完全背包来做。
我们将其假设为完全背包。
dp数组的含义为:到达某一楼梯的方法数(视为某一个容量的方法)
dp的动态更新思路为:可以向背包装入大小为1或者2的物品。
因此,背包的更新算法为for(int j =1;j<=2;j++) { dp[ii]+=dp[ii-j]; }
dp数组的初始化:因为到达0和1个方法只有一种,因此,我们令其为1。
从前向后遍历。

class Solution {
public:
    int climbStairs(int n) {
        if(n<=1) return 1;
        vector<int>dp(n+1,0);
        dp[0] = 1;
        dp[1] = 1;
        for(int ii = 2;ii<=n;ii++)
        {
            for(int j =1;j<=2;j++)
            {
                dp[ii]+=dp[ii-j];
            }
        }
        return dp[n];
    }
};

322.零钱兑换

这道题是要求符合要求的最小硬币数,我们用完全背包进行求解。
首先对背包进行定义。dp[ii]表示,容量为ii的背包最少硬币数。
推导公式:我们遍历某个背包的容量ii时,如果此时有某个容量ii-coins[jj]可以满足,加入一个硬币coins[jj]使得硬币数更少,那么我们更新这个容量的大小,使其为这个更小值。
初始化:我们假设初试dp[0]为零,即没有容量没有硬币,其他容量的数值为INT_MAX,这样方便我们进行求最小值。
我们从小到大进行遍历。

代码

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        vector<int>dp(amount+1,INT_MAX);  
        dp[0] = 0;
        for(int ii =1;ii<amount+1;ii++)
        {
            for(int jj =0;jj<coins.size();jj++)
            {
                if(ii>=coins[jj]&&dp[ii-coins[jj]]!=INT_MAX)
                    dp[ii] = min(dp[ii],dp[ii-coins[jj]]+1);
            }
        }
        if(dp[amount]==INT_MAX) return -1;
        return dp[amount];
    }
};

279.完全平方数

对于该题,我们的思路为确定一个dp数组,用来记录0-n数字所能记录的最少完全平方数,在遍历的过程中,对于数字n,我们从1到根号n(取整)进行遍历,如果存在某种组合的完全平方数的数量使得dp[n]更小,我们就更新dp[n]。

回溯四部曲:
1.dp数组的含义,dp[n]表示对于数字n包含的最少完全平方数。
2.dp数组的推导公式,我们取dp[n]= min(dp[n],dp[n-jjjj]+1),即取当前的dp[n]数量和dp[n-jjjj]的数量+1 的最小值。
3.初试化,我们对dp[0]=0,dp[1]=1,其他数字为INT_MAX,方便我们进行求最小值。
4.从小到大进行遍历。

代码

class Solution {
public:
    int numSquares(int n) {
        vector<int>dp(n+1,INT_MAX);
        dp[0] = 0;
        dp[1] = 1;
        for(int ii =2;ii<n+1;ii++)
            for(int jj =1;jj<=sqrt(ii);jj++)
                dp[ii] = min(dp[ii],dp[ii-jj*jj]+1);
        return dp[n];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值