代码随想录补打卡 518. 零钱兑换 II 377. 组合总和 Ⅳ

文章介绍了使用动态规划解决三个经典问题:518零钱兑换、377组合总和和70爬楼梯。通过遍历不同的物品(或数字)和背包大小(或目标和),计算出满足条件的不同组合数。动态规划表的构建过程展示了如何累加前一状态的信息来得到当前状态的解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

518 零钱兑换

代码如下  

func change(amount int, coins []int) int {

           dp := make([]int,amount+1) 

           dp[0] = 1 

           for i := 0 ; i < len(coins) ; i++ {  先遍历物品

               for j := coins[i] ; j <= amount ; j++ { 在遍历背包

                   dp[j] += dp[j-coins[i]]   举例 dp[3] 如果想要装满3的背包,那么就有三种可能 1+dp[2],2+dp[1],3+dp[0] ,所以总的方法是累加的   

               }

           }

           return dp[amount]

}

注 : 这里是先遍历物品,在遍历背包,所以遍历时候,会将物品1重复的放入各个背包,然后再将2重复的放入各个背包 。举例来说如果用这样的遍历方式装满背包3就有两种情况 一种是1,1,1 另一种是1,2 递推关系式分别为 dp[3] = dp[3] + dp[2] (先装满dp[2],在装入1,对应1,1,1,) dp[3] = dp[3] + dp[1] (对应的是先装满1,在装入2对应1,2,再加上之前的一种方法1,1,1所以此时dp[3]的值为2,即1,2 和1,1,1) 

如果是先遍历背包在遍历物品

for j := 0 ; j <= amount ; j++ {

               for i := 0 ; i < len(coins) ; i++ {

                   if j - coins[i] >= 0 {

                       dp[j] += dp[j-coins[i]]

                   }

               }

           }

还是以dp[3] 为例,那么在遍历dp[3]之前会完成dp[2]的遍历dp[2]为2 即1,1 和 2 两种情况 

此时dp[3] = dp[3] + dp[2]  这个表达式说明此时要放入1 ,是在dp[2]基础上的,即有两种情况 1,1,1,和2,1 。当要放入2时 ,dp[3] = dp[3] + dp[1] 此时又加入一种情况就是1,2 此时dp[3]的值有三种情况,即1,1,1,和2,1和1,2 

377 组合总和

代码如下

func combinationSum4(nums []int, target int) int {  //和上面的思路基本一致,只不过是求排列,所以先遍历背包,在遍历物品 

             dp := make([]int,target+1)

             dp[0] = 1 

             for j := 0 ; j <= target ; j++ {

                 for i := 0 ; i < len(nums) ; i++ {

                     if j >= nums[i] {

                         dp[j] += dp[j-nums[i]]

                     }

                 }

             }

             return dp[target] 

}

70 爬楼梯

代码如下

func climbStairs(n int) int {   思路同上,只不过是物品只要1和2 

         if n == 1 {

             return 1 

         }

         dp := make([]int,n+1)

         m := 2 

         dp[0] = 1 

         for j := 1 ; j <= n ; j++ {

             for i := 1 ; i <= m ; i++ {

                 if j >= i {

                      dp[j] += dp[j-i]

                 }

                

             }

         }

         return dp[n]

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值