动态规划五部曲模板
- dp数组以及下标的含义
- 递推公式
- dp数组如何初始化
- 遍历顺序
- 打印数组
● 70. 爬楼梯 (进阶)
● 322. 零钱兑换
● 279.完全平方数
详细布置
70. 爬楼梯 (进阶)
关联 leetcode 70. 爬楼梯 (进阶)
关联 卡码网:57. 爬楼梯
-
思路
- dp数组以及下标的含义
- dp[i]:爬到有i个台阶的楼顶,有dp[i]种方法。
- 递推公式
- dp[i] += dp [i-j]
- dp数组如何初始化
- dp[0]=1
- 遍历顺序
- 排列问题,顺序有关
- target在外,nums在内
- 打印数组
- dp数组以及下标的含义
-
题解
func climbStairs(n int, m int) int { dp := make([]int, n+1) dp[0] = 1 for i := 1; i <= n; i++ { for j := 1; j <= m; j++ { if i-j >= 0 { dp[i] += dp[i-j] } } } return dp[n] } func main() { // 读取输入n,m reader := bufio.NewReader(os.Stdin) input, _ := reader.ReadString('\\n') input = strings.TrimSpace(input) nv := strings.Split(input, " ") n, _ := strconv.Atoi(nv[0]) m, _ := strconv.Atoi(nv[1]) result := climbStairs(n, m) fmt.Println(result) }
322. 零钱兑换
关联 leetcode 322. 零钱兑换
如果求组合数就是外层for循环遍历物品,内层for遍历背包。
如果求排列数就是外层for遍历背包,内层for循环遍历物品。
-
思路
-
dp数组以及下标的含义
dp[j] : 装满容量为 j 的背包,最少物品为 dp[j]
-
递推公式
dp[j] = min(dp[j-coins[i]] + 1,dp[j] )// +1:加一个数量0
-
dp数组如何初始化
dp[0] = 0//非零下下标, 初始化 int_mx
-
遍历顺序
- 顺序无关
-
打印数组
-
-
题解
func coinChange(coins []int, amount int) int { dp := make([]int, amount+1) dp[0] = 0 maxValue := 2<<31 - 1 for i := 1; i <= amount; i++ { dp[i] = maxValue } for i := 0; i < len(coins); i++ { //物品 for j := coins[i]; j <= amount; j++ { //背包 curBackpackCount := dp[j] goodWeight := coins[i] preGoods := dp[j-goodWeight] preGoodsPlusOne := preGoods + 1 dp[j] = min(curBackpackCount, preGoodsPlusOne) } } if dp[amount] == maxValue { return -1 } return dp[amount] }
279.完全平方数
关联 leetcode 279.完全平方数
本题 和 322. 零钱兑换 基本是一样的,大家先自己尝试做一做
-
思路
-
dp数组以及下标的含义
dp[j] : 凑成容量为 j 的背包,所需的最少元素个数
-
递推公式
dp[j]= min(dp[j],dp[j-nums[i]+1)
-
dp数组如何初始化
dp[0] = 0//非零下标初始化成 n + 1,最小有1,可推出最大就是 n
-
遍历顺序
-
打印数组
-
-
题解
func numSquares(n int) int { dp := make([]int, n+1) dp[0] = 0 for i := 1; i <= n; i++ { dp[i] = n + 1 } goods := getAbsSqrtArray(n) for i := 0; i < len(goods); i++ { for j := goods[i]; j <= n; j++ { dp[j] = min(dp[j], dp[j-goods[i]]+1) } } return dp[n] } func getAbsSqrtArray(num int) []int { ret := make([]int, 0) for i := 1; i <= num; i++ { if i*i <= num { ret = append(ret, i*i) } else { break } } return ret } /*解法二:省略生成完全平方数组*/ func numSquares(n int) int { dp := make([]int, n+1) dp[0] = 0 for i := 1; i <= n; i++ { dp[i] = n + 1 } for i := 0; i*i <= n; i++ { val := i * i for j := val; j <= n; j++ { dp[j] = min(dp[j], dp[j-val]+1) } } return dp[n] }