要发财的小熊猫很靠谱 level
获赞
6
粉丝
5
关注
0
看过 TA
109
门头沟学院
2025
C++
IP属地:江西
暂未填写个人简介
私信
关注
2024-12-14 14:04
门头沟学院 C++
115、不同的子序列://dp[i][j]:以i-1结尾的字符串s中有多少个以j-1结尾的字符串t//递推公式:删除s中的字符以匹配t。//两元素相等时,可以考虑在s中使用该元素,或者不使用该元素。//if(s[i-1] == t[j-1]) dp[i][j] = dp[i-1][j-1] + dp[i-1][j];//else dp[i][j] = dp[i-1][j];//初始化:dp[i][0](t为空字符串)初始化为1,dp[0][j](s为空字符串)初始化为0583、两个字符串的删除操作,使得word1与word2相同//两个字符串的删除操作,就相当于找到两个字符串的最长公共子序列//dp[i][j]:长度[0,i-1]的s1和长度[0,j-1]的s2的最长公共子序列的长度72、编辑距离//要将word1转换为word2难点是当两个元素不相等时,分别取增删替操作中最小的//dp[i][j]:以i-1结尾的word1转换成以j-1结尾的word2最小编辑次数//递推公式:主要分为相等和不相等两种情况的操作//if(word1[i-1] == word2[j-1]) dp[i][j] = dp[i-1][j-1];//else dp[i][j] = min(dp[i-1][j] + 1,//word1删除当前字符//                    min(dp[i-1][j-1] + 1,//word1替换当前字符//                    dp[i][j-1] + 1))//word1插入一个字符//初始化:dp[i][0](word2为空字符,所以要删掉所有word1的元素)初始化为i//dp[0][j](word1为空字符,所以要插入所有word2的元素)初始化为j
0 点赞 评论 收藏
分享
2024-12-11 21:31
门头沟学院 C++
今天完成了三道动规的子序列题,有点难度。最长递增子序列://dp[i]:下标为i时的最长递增子序列的长度//递推公式://if(nums[i] > nums[j]) dp[i] = max(dp[j] + 1, dp[i]);//初始化:全初始化为1//遍历顺序,两层for循环,外层i,内层j(j < i)if(nums.size() == 0) return 0;vector<int> dp(nums.size(), 1);int result = 1;for(int i = 1; i < nums.size(); i++){for(int j = 0; j < i; j++){if(nums[i] > nums[j]){dp[i] = max(dp[j] + 1, dp[i]);}}result = max(result, dp[i]);}return result;//不一定是以最后一个元素为结尾时是最长子序列最长连续递增子序列:简单两个数组间的最长重复数组://dp[i][j]:以i-1为结尾的A和以j-1为结尾的B的最长重复子数组的长度//注意: “以下标i - 1为结尾的A” 标明一定是 以A[i-1]为结尾的字符串//递推公式://if(nums[i] == nums[j]) dp[i][j] = dp[i-1][j-1] + 1;//初始化,全初始化为0,因为dp[i][0],dp[0][j]其实没有意义,而其他的则会被覆盖//遍历顺序:两层for循环if(nums1.size() == 0 || nums2.size() == 0) return 0;vector<vector<int>> dp(nums1.size() + 1, vector<int>(nums2.size() + 1, 0));int result = 0;for(int i = 1; i <= nums1.size(); i++){for(int j = 1; j <= nums2.size(); j++){if(nums1[i-1] == nums2[j-1])//是i-1,j-1时的元素相等{dp[i][j] = dp[i-1][j-1] + 1;}result = max(dp[i][j], result);//持续记录最大值}}return result;这几天终于把Reactor框架学完了!
0 点赞 评论 收藏
分享
2024-12-10 20:34
门头沟学院 C++
继续完成了买卖股票的题(最多交易k次、冷冻期、手续费)最多交易k次://动态规划,最多只能买卖k次--分情况考虑(奇数持有,偶数卖出)//dp[i][j]:i为第几天,j为状态,奇数时是持有,偶数时是不持有//递推公式://dp[i][j+1] = max(dp[i-1][j+1], dp[i-1][j] - prices[i]);//今天之前就持有了或者今天才买入//dp[i][j+2] = max(dp[i-1][j+2], dp[i-1][j+1] + prices[i]);//昨天就不持有或者今天才卖出//初始化:第0天的所有状态都要初始化,偶数为0,奇数为-prices[0];//遍历顺序:外层遍历天数i,内层遍历j状态.if(prices.size() == 0) return 0;vector<vector<int>> dp(prices.size(), vector<int>(2*k+1, 0));for(int j = 1; j < 2*k; j+=2)//更新奇数情况下第0天的值{dp[0][j] = -prices[0];}for(int i = 1; i < prices.size(); i++){for(int j = 0; j < 2*k-1; j+=2){dp[i][j+1] = max(dp[i-1][j+1], dp[i-1][j] - prices[i]);dp[i][j+2] = max(dp[i-1][j+2], dp[i-1][j+1] + prices[i]);}}return dp[prices.size() - 1][2*k];冷冻期://动态规划--不限交易次数,但有冷冻期,即卖出的第二天不能操作//分情况考虑--持有、不持有、冷冻期//递推公式://持有:昨天已持有、今天买昨天之前就卖了、今天买昨天冷冻期//dp[i][0] = max(dp[i-1][0], dp[i-1][1] - prices[i], dp[i-1][3] + prices[i]);//不持有:保持卖出状态(前一天就是保持卖出状态,或者前一天是冷冻期)//dp[i][1] = max(dp[i-1][1], dp[i-1][3]);//不持有:今天卖//dp[i][2] = dp[i-1][0] + prices[i];//冷冻期:昨天卖//dp[i][3] = dp[i-1][2];//初始化:第0天全初始化为0if(prices.size() == 0) return 0;vector<vector<int>> dp(prices.size(), vector<int>(4, 0));dp[0][0] = -prices[0]; // 持股票for(int i = 1; i < prices.size(); i++){dp[i][0] = max(dp[i-1][0], max(dp[i-1][1] - prices[i], dp[i-1][3] - prices[i]));dp[i][1] = max(dp[i-1][1], dp[i-1][3]);dp[i][2] = dp[i-1][0] + prices[i];dp[i][3] = dp[i-1][2];}return max(dp[prices.size() - 1][1], max(dp[prices.size() - 1][2], dp[prices.size() - 1][3]));手续费:简单,在卖出时再减去手续费就行。
0 点赞 评论 收藏
分享
2024-12-09 23:42
门头沟学院 C++
买卖股票的三道题(最多交易1次,2次,不限次数)--动态规划法最多交易1次://动态规划解题(其实贪心会更简单)//dp[i][0]:第i天持有股票的最大利润(持有不代表今天买入)//dp[i][1]:第i天不持有股票的最大利润//递推公式://当天仍然持有,要么是前面买入的,要么是今天刚买入的//dp[i][0] = max(dp[i-1][0], -prices[i]);//当天不再持有,要么是前面就已经不持有(没买过或者已经卖了),要么是今天卖了//dp[i][1] = max(dp[i-1][1], dp[i-1][0] + prices[i]);//初始化:dp[0][0] = -prices[0]; dp[0][1] = 0;交易不限次数:与交易1次唯一不同的点是//当天仍然持有,要么是前面买入的,要么是今天刚买入的(今天可能不是第一次买了)//dp[i][0] = max(dp[i-1][0], dp[i-1][1] - prices[i]);最多交易两次://动态规划,最多只能买卖两次--分情况考虑//每天可能处在5种状态//dp[i][0]:没有操作(其实可以不写,后面4种情况包含了当天啥也没干的情况)//dp[i][1]:第一次持有股票,要么今天刚买入,要么前面已经买入,但还没卖过//dp[i][2]:第一次不持有,要么今天第一回卖出,要么前面已经卖了一回了,今天啥也没干//dp[i][3]:第二次持有,要么今天第二次买入,要么前面已经买了第二次了,到今天还没卖//dp[i][4]:第二次不持有,要么今天第二次卖出,要么前面已经卖第二次了,今天啥也没干//递推公式:dp[i][0] = dp[i-1][0];dp[i][1] = max(-prices[i], dp[i-1][1]);dp[i][2] = max(dp[i-1][1] + prices[i], dp[i-1][2]);dp[i][3] = max(dp[i-1][2] - prices[i], dp[i-1][3]);dp[i][4] = max(dp[i-1][3] + prices[i], dp[i-1][4]);//初始化:dp[0][0] = 0; dp[0][1] = -prices[0]; dp[0][2] = 0;//今天买今天卖//dp[0][3] = -prices[0];今天第二回买。dp[0][4] = 0;//今天第二回卖
0 点赞 评论 收藏
分享
2024-12-08 10:19
门头沟学院 C++
打家劫舍三道题:街道题递推公式:dp[i] = max(dp[i-2] + nums[i], dp[i-1])(当前这户偷还是不偷);围城题就要分两种情况去考虑,分别是不含首元素,和不含尾元素,其它和前面一致;二叉树题比较难,如下:vector<int> traversal(TreeNode* cur){vector<int> dp(2, 0);//递归出口if(cur == nullptr) return {0, 0};//左vector<int> leftdp = traversal(cur->left);//右vector<int> rightdp = traversal(cur->right);//中//不偷当前结点,那么就要考虑偷左右孩子结点(不是一定偷,主要是取最大值)int val1 = max(leftdp[0], leftdp[1]) + max(rightdp[0], rightdp[1]);//偷当前结点,那么左右孩子结点一定不能偷了int val2 = cur->val + leftdp[0] + rightdp[0];return {val1, val2};}int rob(TreeNode* root) {//打家劫舍二叉树//递归采用后序遍历的方式,因为决定偷不偷当前结点是由左右子节点偷不偷决定的//定义一个包含两个元素的一维dp数组(每层递归里都有个dp数组)//dp[0]表示不偷当前结点盗取的最大金额,dp[1]表示偷当前结点盗取的最大金额//递归函数最后返回的也是一个dp数组,表示偷不偷根节点(所有子节点都遍历完了)vector<int> result = traversal(root);return max(result[0], result[1]);}
0 点赞 评论 收藏
分享
2024-12-06 22:14
门头沟学院 C++
0 点赞 评论 收藏
分享
2024-12-04 23:47
门头沟学院 C++
0 点赞 评论 收藏
分享

创作者周榜

更多
关注他的用户也关注了:
牛客网
牛客网在线编程
牛客网题解
牛客企业服务