股票问题:
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
应该用动态规划求解,而不是深度优先搜索,深度优先搜索过于复杂,不是最优解。
**
主要参考
**
**(0-1背包)
**转自:https://blog.csdn.net/huyang0304/article/details/82286279
假如一个小偷携带者一个可以放10kg重的背包,潜入一户人家行窃,家里有4个物品,每个物品只有1个。即价值v[] = {10, 40, 30, 50},重量w[] = {5, 4, 6, 3}。
一维数组法(无须装满)
一维数组(必须装满)
完全背包
转自:https://blog.csdn.net/ls5718/article/details/52227908
有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。(类最大礼物价值)
有 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