![](https://img-blog.csdnimg.cn/20201014180756923.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
动态规划
sorry_maker
博客只图一乐,主要是给我自己看的,不要轻信,有问题欢迎留言
展开
-
978.最长湍流子数组
问题描述思路求最值问题,不用输出具体的结果,只需要输出长度,那么就可以使用动态规划,确定了方法,就可以根据方法的模板来写。首先确定状态,这里的dp数组为2行n列dp[0][j]表示以第j个数字为结尾的,且当前为升序列,也就是第j个数大于第j-1个数。dp[1][j]表示以第j个数字为结尾的,且当前为降序列,也就是第j个数小于第j-1个数。第一行代表状态为升,第二行代表状态为减那么就有了状态转移方程:如果当前状态为升,那么dp[0][j]=dp[1][j-1]+1;如果当前状态为降,那么原创 2020-11-20 16:50:46 · 118 阅读 · 0 评论 -
LeetCode 动态规划72编辑距离
问题描述思路求最值,动态规划问题,首先是确定状态,一般在两个字符串上进行的操作,dp就为二维数组,i,j分别表示考虑word1,word2从0到i,j字符串。状态方程在这里,建议拿纸笔模拟一下,很容易就可以得到代码class Solution {public: int min3(int a,int b,int c) { return min(a,min(b,c)); } int minDistance(string word1, string word原创 2020-10-22 22:10:28 · 80 阅读 · 0 评论 -
leetcode 动态规划494目标和
问题描述思路这是一道关于选择的题目,也就是对于每一个数,都有选+还是选-两种选择。首先确定状态,设数组的位置为变量i,表示考虑数组的第0到i的数,target的数值为j很容易就可以找出状态方程dp[i][j]=dp[i-1][j-nums[i]]+dp[i-1][j+nums[i]];当然要注意边界情况然后这个题目很容易犯错的一点就是,二维数组的列要开所有元素和的两倍加1那么大,表示target从-sum到sum。而且当S大于sum的时候,是没有解的。代码class Solution {原创 2020-10-22 21:11:46 · 117 阅读 · 0 评论 -
LeetCode 动态规划139单词拆分
问题描述思路状态:dp[i]表示考虑0到i-1所表示的字符串可不可以被拆分成单词状态转移方程在程序中有,不难理解代码class Solution {public: bool wordBreak(string s, vector<string>& wordDict) { int n=s.size(); vector <bool> dp(n+1,false); unordered_set <string&原创 2020-10-22 19:04:40 · 123 阅读 · 0 评论 -
leetcode 474 1和0
问题描述思路分析求最值问题,并且需要考虑所有的情况,所以可以用动态规划来写。题中是要选出最大的子集,首先,明确状态,dp[i][j][k]表示考虑第strs[0]到strs[i],0的个数为j,1的个数为k的最大子集。对应每一个字符串,就有选还是不选的问题。所以状态方程是dp[i][j][k]=max(dp[i-1][j][k](不选),dp[i-1][j-num0][k-num1]+1(选));然后还有一个步骤就是初始化的问题,那就是考虑第一个字符串对应的dp数组应该如何写,具体见代码代码原创 2020-10-20 16:36:30 · 76 阅读 · 0 评论 -
LeetCode377组合总和4
问题描述状态转移方程为当数组不越界的情况下(i-nums[j]>=0)dp[i]=sum(dp[i-nums[j]]);代码class Solution {public: int combinationSum4(vector<int>& nums, int target) { int n=nums.size(); if(target<=0||n==0) return 0; vector <unsign原创 2020-10-20 14:59:17 · 85 阅读 · 0 评论 -
LeetCode 动态规划322零钱兑换
问题描述思路根据题意,最暴力的方法就是枚举所有的情况,并且是求最值问题,所以就可以想到用动态规划的方法进行求解代码class Solution {public: int coinChange(vector<int>& coins, int amount) { int n=coins.size(); if(amount==0) return 0; if(n==1&&amount%coins[0]!=0)原创 2020-10-20 14:28:00 · 86 阅读 · 0 评论 -
leetcode 416.分割等和子集
问题描述思路本题可以看做能否将n个物体放入容量恰好为sum/2的背包中,是一个典型的背包问题状态转移方程为如果当前物体(第i个)可以放得下,也就是if(sums[i]<=c)dp[i][c]=(dp[i-1][c]||dp[i-1][c-sums[i]]);即考虑0到i个物品能不能恰好放入容量为c的背包,就要考虑第i个物品放还是不放,如果放,那就是考虑0到i-1个物品能不能恰好放入容量为c-sums[i]的背包,,如果不放,就考虑能否将0到i-1个物品能不能恰好放入容量为c的背包。如果原创 2020-10-16 11:07:01 · 54 阅读 · 0 评论 -
LeetCode 121 买卖股票的最佳时期 动态规划
问题描述思路要遍历所有的情况,并且有重叠子问题,就可以考虑使用动态规划的思想来求解1.首先就是确定dp[i]该表示什么,本题就按照题目意思来,表示第i天以前的最大利润2.状态方程 本题为 dp[i]=max(dp[i−1],prices[i]−minprice),第i天要么什么都不做,要么在第i天卖出股票,所得的利润才可能是最大的3.初始化 dp[0]=0;代码代码class Solution {public: int maxProfit(vector<int&g原创 2020-09-21 19:02:09 · 73 阅读 · 0 评论 -
动态规划LeetCode309最佳买卖股票时期含冷冻期
问题描述思路读完题目,就知道要求出所有可能的情况,可以使用递归。然后可以发现递归求解过程中会有重叠子问题,所以就采用动态规划的方法。用一个二维数组来保存状态。总共三列,第一列表示持有股票,第二列表示未持有股票且处于冷冻期,第三列表示未持有股票且未处于冷冻期,dp[i]表示这天结束后的最大收益,每个dp[i]只与昨天也就是dp[i-1]有关。不难理解,只要昨天对应的三种状态的收益是最大的,在这个基础上进行相关操作,就能确保今天的收益是最大的代码class Solution {public:原创 2020-09-21 11:03:13 · 115 阅读 · 0 评论 -
LeetCode 213 打家劫舍 动态规划
问题描述该题就是在打家劫舍1的基础上增加了一个条件,就相当于求两次打家劫舍1,因为要想偷得钱最多,就要分两种情况:在第一个和最后一个中选择哪个(两个都不选的舍去,那肯定不是最大的)偷到的钱是最多的;代码class Solution {public: int f(vector <int> &nums,int s,int e)//相当于打家劫舍1 { vector <int> dp(nums.size()); dp[s]=原创 2020-09-20 20:46:13 · 67 阅读 · 0 评论 -
动态规划LeetCode 337打家劫舍3
问题描述题解我曾试用递归的方法来做这个题目,超时了;所以就尝试用记忆化搜索来写,其实也就是动态规划,,那怎样保存数据呢?这里就要用到容器 unordered_map,关于其使用方法可以去百度一下,这个东西就是一个无序的映射,就是插入元素不会自动进行排序。具体用法见代码代码/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * Tree原创 2020-09-20 20:38:48 · 94 阅读 · 0 评论 -
动态规划Leetcode63不同路径2
题目代码class Solution {public: int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) { int m=obstacleGrid.size(),n=obstacleGrid[0].size(); vector <vector<int>> dp(m+1,vector <int> (n,0));原创 2020-09-04 20:59:37 · 86 阅读 · 0 评论 -
动态规划leetcode62不同路径
问题描述代码class Solution {public: int uniquePaths(int m, int n) { if(m==0||n==0) return 0; vector <vector <int>> dp(m,vector <int> (n,1)); for(int i=m-2;i>=0;i--) { for(int j=n-2;j>=0;j--) {原创 2020-09-04 20:06:34 · 56 阅读 · 0 评论 -
动态规划LeetCode91.解码方法
问题描述代码class Solution {public: int numDecodings(string s) { int n=s.size(); vector <int> dp(s.size()+1,1); if(s[0]=='0') return 0; for(int i=2;i<=n;i++) { if(s[i-1]=='0') { if(s[i-2]=='1'||s[i-2]=='2'){原创 2020-09-04 19:56:20 · 111 阅读 · 0 评论 -
动态规划leetcode279完全平方数
题目描述思路一般求最值问题,或者是有重复步骤的问题,都可以用动态规划来解函数表达式求***f(i)=min(f(i-1),f(i-4),f(i-9)…………)+1***在不越界的情况下代码class Solution {public: int numSquares(int n) { vector<int> dp(n+1,INT_MAX); dp[0]=0;//为什么初始化为0,下文有讲 dp[1]=1; for原创 2020-09-04 19:20:37 · 111 阅读 · 0 评论 -
动态规划leetcode 343整数拆分
问题描述思路注意事项此题的有一个坑,,,首先明白函数的定义是:将i分割,获得的最大乘积但是我们在计算的时候需要考虑不分割的情况,即直接用j*(i-j)代码class Solution {private: int max3(int a,int b,int c) { return max(a,max(b,c)); }public: int integerBreak(int n) { vector <int> d原创 2020-09-04 16:11:07 · 108 阅读 · 0 评论 -
动态规划leetcode 64最小路径和
与leetcode 120 三角形最短路径和类似class Solution {public: int minPathSum(vector<vector<int>>& grid) { int m=grid.size(); int n=grid[0].size(); vector <vector <int>> dp(m,vector <int> (n,0)); dp.原创 2020-09-04 15:37:26 · 129 阅读 · 0 评论 -
动态规划leetcode 120三角形最小路径和
思路动态规划问题就是找函数表达式,本题的函数表达式就是f[i][j]代表第i行第j列的数字到三角形低端的最短距离f[i][j]=min(f[i+1][j],f[i+1][j+1])+triangle[i][j];代码class Solution {public: int minimumTotal(vector<vector<int>>& triangle) { int n=triangle.size(); if(n==0).原创 2020-09-04 15:04:00 · 102 阅读 · 0 评论