动态规划
DP
梅杏柿
这个作者很懒,什么都没留下…
展开
-
Leetcode第514题 自由之路C++解法
先递归吧。果不其然,字符串的时候就超时了。毕竟是指数级。class Solution {public: int findDis(string& ring,int pos,string& key,int pmove) { int m=ring.size(),n=key.size(); if(pmove==n) return 0; if(ring[pos]==key[pmove])原创 2021-02-22 13:02:06 · 128 阅读 · 1 评论 -
Leetcode第64题 最小路径和C++解法
DP就完事了,就是需要注意边界条件class Solution {public: int minPathSum(vector<vector<int>>& grid) { int m=grid.size(),n=grid[0].size(); int dp [m+1][n+1]; memset(dp,0,sizeof(dp)); for(int i=1;i<=m;++i)原创 2021-02-21 20:55:54 · 115 阅读 · 0 评论 -
Leetcode第1312题 让字符串成为回文串的最少插入次数C++解法
刚做过编辑距离的,我就想直接复制一个反转字符串,然后这两个字符串相同,前几个还可以的,但是到“leetcode”这个时,就不行了。仔细想这两个问题还是不等价,72题中的编辑距离中的操作包括更改操作,但是本题中的操作只有插入,所以果然不行。然后我又想从两边向中间靠拢,leetcode倒是通过了,第18个案例"zjveiiwvc"就通不过了class Solution {public: int minInsertions(string s) { int n=s.size();原创 2021-02-21 19:42:42 · 286 阅读 · 0 评论 -
Leetcode第72题 编辑距离 C++解法
这动态规划算法也太精妙了……class Solution {public: int minDistance(string word1, string word2) { int m=word1.size()+1,n=word2.size()+1; int dp[m][n]; for(int i=0;i<m;++i) dp[i][0]=i; for(int j=0;j<n;++j) dp[0][j]=j; f原创 2021-02-21 17:43:20 · 113 阅读 · 0 评论 -
Leetcode第312题 戳气球C++解法
事实证明,我还是不会做……没有任何逻辑推导,这是硬做啊class Solution {public: int maxCoins(vector<int>& nums) { int n=nums.size(),res=0; if(n==1) return nums[0]; if(n==2) return nums[0]*nums[1]+(nums[0]>nums[1]?nums[原创 2021-02-21 10:06:03 · 168 阅读 · 0 评论 -
Leetcode第887题 鸡蛋掉落C++解法
经典问题,想了一个小时无果,只能看答案。当然自己还是菜,连递归都没想出来。总结就是看第i层的鸡蛋是否碎了,碎了的话,就往下扔,但是鸡蛋要少一个,没碎的话楼层就往上,鸡蛋不变。不管结果如何,最终的结果是要包含所有情况,所以要取最大值。但是不管往上还是往下,扔的次数都加一。但是怎么选i?那就是枚举了,通过枚举我们找出最佳楼层(也就是最小值)class Solution {public: int superEggDrop(int K, int N) { if(N<=1)原创 2021-02-20 17:58:25 · 438 阅读 · 0 评论 -
Leetcode第5题 最长回文子串C++解法
没动态规划出来,就做不出来……class Solution {public: string longestPalindrome(string s) { int n=s.size(); if(n<2) return s; int dp[n][n],pos=0,len=1; memset(dp,0,sizeof(dp)); for(int i=1;i<n;++i) {原创 2021-02-20 10:14:03 · 158 阅读 · 0 评论 -
Leetcode第309、714题 买卖股票的最佳时机C++解法
动态规划class Solution {public: int maxProfit(vector<int>& prices) { int n=prices.size(); if(n<2) return 0; int buy[n],sell[n],froze[n]; buy[0]=-prices[0],sell[0]=0,froze[0]=0; for(int i=1;i<n;++i)原创 2021-02-18 17:23:21 · 56 阅读 · 0 评论 -
Leetcode第123、188题 买卖股票的最佳时机 C++解法
都是用动态规划去做;123题class Solution {public: int maxProfit(vector<int>& prices) { int size=prices.size(); int buy1=-prices[0],sell1=0,buy2=-prices[0],sell2=0; for(int i=1;i<size;++i) { sell2=max(sell原创 2021-02-18 12:21:44 · 103 阅读 · 0 评论 -
Leetcode第121、122题 买卖股票的最佳时机C++解法
第121题class Solution {public: int maxProfit(vector<int>& prices) { int res=0; int low=prices[0]; for(int p:prices) { low=min(low,p); res=max(res,p-low); } return res;原创 2021-02-18 08:04:27 · 65 阅读 · 0 评论 -
Leetcode213题 打家劫舍 II C++解法
先上笨蛋解法,环形偷的关键在于nums[0]和nums[n-1]不会同时被访问,所以设置两个数组,一个从头偷,一个从尾偷。最终比较从头偷还是从尾偷的数大。class Solution {public: int rob(vector<int>& nums) { if(nums.empty()) return 0; if(nums.size()==1) return nums[0]; int n=nu原创 2021-01-19 15:50:46 · 143 阅读 · 0 评论 -
Leetcode第198题 打家劫舍 C++解法
确实简单,列出状态转移方程就出来了。dp[i]=max(dp[i-1],dp[i-2]+nums[i-1])class Solution {public: int rob(vector<int>& nums) { if(nums.empty()) return 0; int n=nums.size(); vector<int> dp(n+1,0); dp[1]=nums[0];原创 2021-01-19 14:16:47 · 176 阅读 · 0 评论 -
Leetcode动态规划hard题收录
编辑距离鸡蛋掉落原创 2021-01-19 14:09:28 · 190 阅读 · 0 评论 -
Leetcode第651题 4键键盘 C++解法
我承认自己有取巧的成分,这个不能算是最佳思路,我归纳了前10个,分析出来1、小于6的情况下,dp[i]=i;2、在超出6的情况下,dp[i]只有两种最大可能,要么是经过C-A,C-C,C-V,C-V,C-V要么是经过了C-A,C-C,C-class Solution{public: int fourkeys_keyboard(int n) { vector<int> dp(n + 1, 0); for (int i = 1; i <原创 2021-01-19 13:50:26 · 285 阅读 · 0 评论 -
Leetcode第10题 正则表达式匹配 C++动态规划解法
这道题难为了我快一天了。看了官方的解法,不得的说,他的解法既巧妙,又复杂。实际上这道题的第五个条件很重要。5、保证每次出现字符 * 时,前面都匹配到有效的字符。也就是说不可能出现p字符串第一个字符为 * 的情况。得出动态转移方程也并不难,但是这个方程里面是有几个坑的。而官方解法是采用了matches去避免。这里我们就直接上图说明。 如果p[i]=* , f[i][j]=f[i-1][j] or f[i][j-2] 。这一步大家都能理解,但是坑也就在这里。如果s=“c”,p=“a*c”。这种情原创 2021-01-19 09:59:45 · 321 阅读 · 0 评论 -
Leetcode第354. 俄罗斯套娃信封问题
在做了第300题 最长递增子序列C++解法之后,得到思路,但毫无疑问,还是暴力解法。class Solution {public: int maxEnvelopes(vector<vector<int> >& envelopes) { if(envelopes.empty()) return 0; sort(envelopes.begin(),envelopes.end(),[](const vector<in原创 2021-01-18 09:57:32 · 98 阅读 · 0 评论 -
Leetcode第300题 最长递增子序列C++解法
真是个辣鸡,暴力动态规划写了半天才通过。class Solution {public: int lengthOfLIS(vector<int>& nums) { if(nums.empty()) return 0; int n=nums.size(),res=1; vector dp(n,1); for(int i=1;i<n;++i) { for(i原创 2021-01-17 22:41:01 · 195 阅读 · 0 评论 -
Leetcode第516题 最长回文子序列 C++解法
想着复制一个反转的字符串,这样问题就转化为了最大子序列。class Solution {public:int longestCommonSubseq(string &s,string &t){ int m=s.size(),n=t.size(); vector dp(n+1,0); int temp,pre; for(int i=0;i<m;++i) { pre=dp[0]; for(int j=1;j&原创 2021-01-17 21:28:37 · 208 阅读 · 0 评论 -
Leetcode第322. 零钱兑换 C++解法
这道题和518. 零钱兑换 II有相似之处。不同的是518求的是所有组合,而这道题求的最小兑换数量。所以采取的方法也不一样。这里外层循环是金额,内层循环是硬币。而求组合数量那里,外层是硬币,内层是数量。解答的时候还是遇到一点问题,我本来是想用INT_MAX,却发现通过不了,最大值变成了-1,想不出其他办法,只能用amount+1来代替。最后做个检测。写到刚才一个字的时候,突然想起,最开始的判断也没有必要了,因为dp[0]是0,所以返回必然是0。class Solution {public:原创 2021-01-17 20:00:14 · 343 阅读 · 0 评论 -
Leetcode第435. 无重叠区间 C++解法
class Solution {public: int eraseOverlapIntervals(vector<vector<int> >& intervals) { int i,res=0; sort(intervals.begin(), intervals.end(), [](const auto& u, const auto& v) { if(u[0]<v[0])原创 2021-01-17 14:56:56 · 248 阅读 · 0 评论 -
Leetcode第518题 零钱兑换 II C++解法
看这道题,一开始想着用有点类似斐波那契数列数组去做,f[n]=sum(f[n-cion[i]])。但是列了一下发现不行,有重合情况。这是想着用一行数组去解决,自然不行,所以还是对动态规划不清楚,最原始的是要列mXn行。dp[i][j]=dp[i-1][j]+dp[i][j-coins[i-1]]。这里的道理自己也说的不清楚。首先第一项肯定是不选第i个硬币的情况的,等于dp[i-1][j]这没什么问题,接下来是dp[i][j-coins[i-1]]。这一项是什么呢?是在使用第i个硬币的情况,但为什么是在第原创 2021-01-16 17:38:15 · 118 阅读 · 0 评论 -
Leetcode第416题 分割等和子集C++解法
这道题解法很清晰,用DP去做,但是我第一次做是直接套背包解法,转移方程也没有变,是的。我就是这么废;class Solution {public: bool canPartition(vector<int>& nums) { int x=0; x=3|1; cout<<x; int i,j,sum=0,n=nums.size(); for(i=0;i<nums.size();++原创 2021-01-16 16:20:54 · 216 阅读 · 0 评论 -
Leetcode第712题 两个字符串的最小ASCII删除和C++解法
昨晚上走之前脑子里混乱就是想不透,回去列了下,是想明白了。主要在于初始化dp[0][i]和dp[j][0]。然而大早上来还是总是报错,而且是错了一次,找的时候还没意识到第二次是相同的错误,就是字符串序号比dp序号少1.class Solution{public: int minimumDeleteSum(string s1, string s2) { int m = s1.size(), n = s2.size(); int dp[m + 1][n +原创 2021-01-14 08:16:02 · 99 阅读 · 0 评论 -
Leetcode第583题 两个字符串的删除操作 C++解法
刚开始对这题毫无头绪,想了几分钟,才意识到可以用求最长公共子序列去做。只要求出LCS,size1+size2-2*LCS即为结果。class Solution {public:int longestCommonSubsequence(string text1, string text2) { int dp[text2.size()+1],pre,temp,res=0;; memset(dp,0,sizeof(dp)); for(int i=1;i<=text1.size(原创 2021-01-13 19:13:47 · 130 阅读 · 0 评论 -
Leetcode第1143题 最长公共子序列C++解法
这个应该是动态规划入门题。很多讲动态规划的都是用这道题去讲。class Solution {public: int longestCommonSubsequence(string text1, string text2) { vector<int> p(text2.size()+1,0);//注意这里数组开辟大小要加一 //一开始运行总有问题,但就是没想到这个 vector<vector<int> > dp(te原创 2021-01-13 18:47:55 · 200 阅读 · 0 评论 -
Leetcode第53题 最大子序和C++解法
之前动态规划不是很清楚,所以看了答案做了,不清楚,恶补了下DP后再来重新做;class Solution{public: int maxSubArray(vector<int> &nums) { int res=INT_MIN,add=0; for(int num : nums) { if(add+num>num) add+=num;原创 2021-01-13 17:07:32 · 69 阅读 · 1 评论 -
动态规划学习笔记
从某种意义上看,动态规划就是带记忆的递归。它比递归优秀的地方在于首先省去了很多不必要的重复计算,优化了时间复杂度。如果只保留最近的状态的话,还能压缩空间,优化了空间复杂度。...原创 2021-01-12 21:29:28 · 44 阅读 · 0 评论 -
Leetcode第78题 子集
笨方法去解,中间设置了好多无关变量,不然vector在尾插的时候会报错class Solution {public: vector<vector<int>> subsets(vector<int>& nums) { set<int> s; for(int i=0;i<nums.size();i++) s.insert(nums[i]); vector<vec原创 2021-01-12 12:43:08 · 70 阅读 · 0 评论 -
Leetcode第152题乘积最大子数组
果不其然,错都跟标准错法一样,目前来说动态规划还是很吃力。就写出这个错法就废了不少劲。class Solution{public: int maxProduct(vector<int> &nums) { int result = nums[0]; int length = nums.size(); vector<int> s(length, 1); s.resize(leng原创 2021-01-12 10:42:23 · 76 阅读 · 0 评论