动态规划问题

动态规划

股票问题:
https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/solution/yi-ge-fang-fa-tuan-mie-6-dao-gu-piao-wen-ti-by-lab

背包问题

剑指offer47:礼物的最大价值
在一个 m*n 的棋盘的每一个格都放有一个礼物,每个礼物都有一定价值(大于 0)。从左上角开始拿礼物,每次向右或向下移动一格,直到右下角结束。给定一个棋盘,求拿到礼物的最大价值。例如,对于如下棋盘:

1 10 3 8
12 2 9 6
5 7 4 11
3 7 16 5

应该用动态规划求解,而不是深度优先搜索,深度优先搜索过于复杂,不是最优解。
动态规划问题_第1张图片

背包问题全解:

**

https://blog.csdn.net/sinat_30973431/article/details/85119871

主要参考

**
**(0-1背包)
**转自:https://blog.csdn.net/huyang0304/article/details/82286279
假如一个小偷携带者一个可以放10kg重的背包,潜入一户人家行窃,家里有4个物品,每个物品只有1个。即价值v[] = {10, 40, 30, 50},重量w[] = {5, 4, 6, 3}。
动态规划问题_第2张图片
一维数组法(无须装满)
动态规划问题_第3张图片
一维数组(必须装满)
动态规划问题_第4张图片

完全背包
转自:https://blog.csdn.net/ls5718/article/details/52227908
有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。(类最大礼物价值)
动态规划问题_第5张图片

戳气球

有 n 个气球,编号为0 到 n-1,每个气球上都标有一个数字,这些数字存在数组 nums 中。

现在要求你戳破所有的气球。每当你戳破一个气球 i 时,你可以获得 nums[left] * nums[i] * nums[right] 个硬币。 这里的 left 和 right 代表和 i 相邻的两个气球的序号。注意当你戳破了气球 i 后,气球 left 和气球 right 就变成了相邻的气球。

求所能获得硬币的最大数量。

说明:

你可以假设 nums[-1] = nums[n] = 1,但注意它们不是真实存在的所以并不能被戳破。
0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100
示例:

输入: [3,1,5,8]
输出: 167
解释: nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
coins = 315 + 358 + 138 + 181 = 167

之后把这道题放了好久,刚刚看的时候突然想到,这种动态规划的题,重点不就是 状态转移方程么!!?于是果断思考中途戳某个气球 i 的情况:

设 动态规划数组 dp[m][n]:nums[m…n]区间内 能戳破气球获得的最大值
取 m < k < n,假设nums[k] 是最后一个戳破的气球,则dp[m][n] = Math.max(dp[m][k]+dp[k][n]+nums[m]*nums[k]*nums[n]);
所以三层循环嵌套

外层循环区间间隔,也即每组气球的个数,2~nums.length;
中层获取每组气球的起始下标
内层获取戳破的气球

class Solution {
    public int maxCoins(int[] nums) {
        int[] coins = new int[nums.length+2];
        int dp[][] = new int[coins.length][coins.length];
        coins[0] = 1;
        coins[coins.length-1]=1;

        for(int i=0;i

你可能感兴趣的:(动态规划问题)