
dp
鸣蜩二九~
一岁有一岁的味道,一站有一站的风景。
花会沿路盛开,以后的路也是。
展开
-
LeetCode 猜数字大小 II(dp)
题目传送最开始想二分了,但是实际上是不能分的。因为每一个分的点实际上没有什么规律(自我感觉)。dp:数据只有200,那说明可以跑三个for。先假设区间(i,j),那么是俩for,再枚举一个点x,在区间(i,j)内。那么要保证必胜的策略假设,必须考虑最坏的最好情况。那么当选中一个点的时候,分成俩个区间(i,x-1)和(x+1,j),因为考虑最坏情况,所以x点就不是最坏了,还得继续分区间。那么这个时候选错的代价就是x+max(dp【i】【x-1】),dp【x+1】【j】)。这个时候,只需要枚举每一个在(i原创 2021-11-12 23:11:42 · 747 阅读 · 0 评论 -
LeetCode 最长定差子序列(dp)
题目传送思路:dp,记录一下当前的数减去等差值在当前数的前面出现过没有,如果出现过,则直接在前面的基础上加一即可。然后记录最大值AC代码class Solution {public: int longestSubsequence(vector<int>& arr, int difference) { int len = arr.size(); int Max = 1,dp[100005] = {0}; map<in原创 2021-11-05 19:05:55 · 106 阅读 · 0 评论 -
leetcode 91. 解码方法(dp)
下定决心,好好过一天~题目传送思路:状态要找对,不然情况会很复杂俩种状态:1.一个数字独立成字母时。 当是s【i】!= ‘0’ 时,dp【i】 = dp【i-1】,否则该情况对答案无贡献2. 俩个数字成字母时。当s【i-1】和s【i】的和小于等于26,且s【i-1】不等于0时。dp【i】 += dp【i-2】AC代码class Solution {public: int numDecodings(string s) { int len = s.size(); s原创 2021-07-29 21:49:50 · 139 阅读 · 0 评论 -
leetcode 45. 跳跃游戏 II(dp)
题目传送思路:dp,状态为:维护到每一个点的最小步数class Solution {public: int jump(vector<int>& nums) { int dp[10005]; fill(dp,dp+10005,1e9+7); dp[0] = 0; for(int i = 0;i < nums.size();i++) { for(int j = 1;原创 2021-07-27 11:08:58 · 174 阅读 · 0 评论 -
leetcode 超级丑数 (dp)
题目传送思路:递推,dp每次选取一个最小臭数,dp【i】,但是最重要的如何维护,使得每次精准求出第i个丑数。1.那么第一个丑数必定是12.第二个丑数,则需要借助前面的丑数来进行计算。现在令pos数组全为0,我们可以想想,我们用每一个质数来乘以它当前能乘的最小丑数(重复的和已经计算过的除外)。那么pos数组则对应每一个质数能乘的最小丑数(肯定是先乘最小的才能维护到准确的第i个丑数呀)3.那么pos还要进行相应的处理。当选中了准确的第i个丑数后。那么对应的那个质数所能乘的最小丑数又要变化了,我们令原创 2021-07-27 10:45:04 · 215 阅读 · 0 评论 -
最小路径和 (dp)
题目传送class Solution {public: int minPathSum(vector<vector<int>>& grid) { int n = grid.size(),m = grid[0].size(); int dp[205][205]; int arr[205][205]; for(int i = 1;i <= n;i++) { f原创 2021-06-13 16:36:26 · 91 阅读 · 0 评论 -
不同路径 (dp)
题目传送思路:很简单,直接设置左上角为1,dp[i][j] = dp[i-1][j] + dp[i][j-1]class Solution {public: int uniquePaths(int m, int n) { long long dp[105][105] = {0}; memset(dp,0,sizeof(dp)); dp[1][1] = 1; for(int i = 1;i <= n;i++)原创 2021-06-13 16:19:42 · 83 阅读 · 0 评论 -
计算各个位数不同的数字个数 (dp)
下定决心,好好过一天 ~题目传送思路:首先数位dp是肯定可以的,只不过状态需要压缩。利用二进制形式进行压缩。但是这个题没有想象那么复杂。直接递推即可,dp[ i ] 代表 拥有 i 位数的合法的数。那么就是 9 * 9 * 8 * 7 … 第一位不能选零。其实更像组合数学。class Solution {public: int countNumbersWithUniqueDigits(int n) { int dp[20] = {0}; dp[0] =原创 2021-06-10 22:21:01 · 349 阅读 · 0 评论 -
打家劫舍 (dp)
下定决心,好好过一天 ~题目传送这是简单版本。思路:如果拿第 i 个物品,一定可以拿第 i-2 或者 i-3 个物品,那么动态方程就出来了,直接i从0往后遍历即可。dp[i] = max(nums[i] + dp[i-2] , nums[i] + dp[i-3]),输出dp数组中最大值即可class Solution {public: int rob(vector<int>& nums) { int dp[1005] = {0}; i原创 2021-06-10 00:39:33 · 147 阅读 · 0 评论 -
分割回文串 (dp)
下定决心,好好过一天 ~题目传送思路:首先还是O(n2)的复杂度把,所有的回文子串都标记上,接下来就可以O(1)查询子序列i到j是否为回文串。接下来再来推另外一个动态方程。设pos[i]表示,以i位置结束的,子序列0到i最少可以分割为多少个符合条件的序列。那么从最开始递推,如果0到i本来就是回文,那么直接pos[i] = 0,否则。再来一个for,枚举位置j,判断j 到 i 是否为回文,如果为回文,那么维护最小值 pos[i] = min(pos[i] , pos[j-1] + 1),这个1就为j到i这原创 2021-06-09 00:16:22 · 189 阅读 · 0 评论 -
整数拆分 (dp,数学)
下定决心,好好过一天 ~题目传送思路:在本子写写就知道。2只能拆成 1 * 1,3 为 1 * 2可以看到,这俩个数拆了过后,他的乘积形式都比自身还小。那么就没必要4 为 2 * 25 为 2 * 36 为 3 * 37 为 3 * 2 * 28 为 3 * 3 * 39 为 3 * 3 * 2 * 210 为 3 * 3 * 3 * 2那么规律就出来了,第n个数的前一个数,如果有2的存在,那么直接把这个2变成3(n比n-1多1)如果没有2,那么就得拆成俩个2出来,原因是,只有原创 2021-06-07 20:06:22 · 277 阅读 · 2 评论 -
最大子序列和(dp)
下定决心,好好过一天 ~题目传送题目思路:简单的dp,注意下边界就行了。当前面的序列为负,那么对后面的序列将是累赘,那么就抛弃前面的序列。class Solution {public: int maxSubArray(vector<int>& nums) { int len = nums.size(); long long dp[100005] = {0}; fill(dp,dp+100005,-1e18);原创 2021-06-07 00:01:00 · 80 阅读 · 0 评论 -
leetcode 最长回文子串(dp)
下定决心,好好过一天 ~题目传送思路:动态转移方程:i到j为回文的话,那么 dp[i][j] 成立的条件就是 dp[i+1][j-1] 成立,就是说他如果是回文,那么他的中间也必定是回文。再处理一下边界和初始化,从每个位置枚举长度,递推即可class Solution {public: string longestPalindrome(string s) { int len = s.size(); bool dp[1005][1005] = {0};原创 2021-06-03 18:23:21 · 83 阅读 · 0 评论 -
洛谷 - P1280 尼克的任务 (线性dp)
题目传送题意:思路:子问题就是选这个任务还是不选这个任务的问题,但是题目有限制要求,当前时间有任务但是自己目前空闲,就必须接一个任务那么如果从头开始找,前面的子问题会对后面的子问题有影响,那么不行,如果从后面往前,那么无后效性成立,动态转移方程式就是,如果此时没有必须的任务要去做,那么dp[i] = dp[i+1] +1,否则这个时刻必定要选一个任务,那么直接加上一个dp[结束时间]。由于无后效性,肯定不会有影响AC代码#include<bits/stdc++.h>#includ原创 2020-12-03 23:31:13 · 349 阅读 · 0 评论 -
洛谷 - P2758 编辑距离(线性dp)
题目传送题意:思路:四种子问题:增 ,删,改,不变那么定义dp数组俩个状态 : 字符串a的前i个字符转化成字符串的前j个字符所需要的次数1.保持当前状态 dp[i][j] = dp[i][j]2.dp[i][j] = dp[i-1][j] a的前i个字符转化成b的前j个字符 等于 把a的前i-1个字符转化成b的前j个字符,那么删一个即可3.dp[i][j] = dp[i][j-1] a的前i个字符 转化成 b的前j-1个字符 ,那么在此基础上再添一个字符即可4.改变,那么等于dp[i-1原创 2020-12-03 21:43:06 · 175 阅读 · 0 评论 -
Codeforces Round #658 (Div. 2) D. Unmerge(分块,背包dp)
题目传送思路:首先得观察到一个规律,如果某个数的后面紧跟着的数中有一段比他小的数,那么这一段数肯定是在一个数组中的,例: 5 3 1 4 2 10 7 8 9 6 ,那么可以分成三段 [5 3 1] ,[4 2] ,[10 7 8 9 6],那么分段有什么意义呢?我们知道了可以把这些段分出来,那么我们现在就可以把段自由组合一下,如果能组合成一个长度为n的数组,那么就成立了,如何自由组合?这很像背包dp,代价为段的长度,价值也为段的长度AC代码#include <bits/stdc++.h&g原创 2020-07-22 18:13:51 · 209 阅读 · 0 评论 -
洛谷 - P1799 数列 (线性dp)
题目传送题目:思路:原创 2020-06-17 17:45:50 · 311 阅读 · 0 评论 -
洛谷 - 摆花 (dp或dfs记忆化搜索)
题目传送题目:思路:动态转移方程为: dp[i][j] = dp[i][j] + dp[i-1][j-k]。前i种花摆j盆花的摆法为:前i-1种花,摆j-k盆花的的摆法总数,另外k盆由第i种花摆出还可以由记忆化搜索做出来,这里不贴代码了。AC代码#include <bits/stdc++.h>inline int read(){char c = getchar();int x = 0,s = 1;while(c < '0' || c > '9') {if(c ==原创 2020-06-03 23:10:18 · 298 阅读 · 0 评论 -
洛谷 - [SHOI2002]滑雪 (dp)
题目链接题意:给你一个二维数组,每个点有一个权值(山的高度),现在只能从高度高的点往下移动,问最长路径是多少。思路:dp思想,寻找最优子结构,很容易知道,在一个点,以这个点为结束点的最长路径为:以其四周(上下左右)的点为结束点的前一个点的最大值加一(前提是他的高度大于结束点)。本来以为自己亲手a掉了,高兴坏了,结果还是wa了,为什么呢?以为dp思想要求无后效性(也就是前面的结果对后面的子结构不会有影响,官方定义为:某阶段的状态一旦确定,则此后过程的演变不再受此前各种状态及决策的影响),那么我们就要原创 2020-06-02 21:43:17 · 459 阅读 · 2 评论 -
洛谷 - 挖地雷( dp , dfs搜索 )
题目传送题意:给你n个地窖,每个地窖有一定的地雷,再给出地窖的连通情况,(单向边) 问你最多能挖走多少地雷。思路:这个题由于,数据不大(n <= 20)所以可以dfs爆搜直接a了。但是他也可以用dp的思想来做,f[i]表示以 i 地窖结束的所挖的最大地雷数arr[i] 表示该地窖的地雷数dp递推方程:当 j 到 i 有路可走时候f[i] = max(f[j]) + arr[i]。dfs代码:#include <bits/stdc++.h>inline int r原创 2020-06-02 11:36:06 · 349 阅读 · 0 评论 -
洛谷 - LIS (最大上升子序列模板题) (dp,二分,贪心)
题目链接题目:思路:这是最大上升子序列的模板题,为dp思想。dp动态方程为: 当a[i] 大于 a[j] 时 f[i] = max( f[j] + 1 , f[i] ),其中f[i]表示的是以这个数结尾的最长子序列,a[i]表示的是i这个位置的数。dp代码:#include<iostream>#include<cstdio>#define ll long long#define rg register intusing namespace std;int n原创 2020-05-31 18:36:25 · 656 阅读 · 0 评论 -
洛谷 - [USACO1.5][IOI1994]数字三角形 Number Triangles (dp入门题)
题目链接题目:dp入门题,因为数据的原因好像也可以暴力搜索过这个题,但是我是来学dp的。。。。。。博主初学。。。。。详情代码思路:从这个数字三角形的下方开始寻找最优子结构。AC代码#include <bits/stdc++.h>inline int read(){char c = getchar();int x = 0,s = 1;while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}whil原创 2020-05-26 22:35:25 · 205 阅读 · 0 评论 -
洛谷 - 最大加权矩形 (前缀和,dp,矩阵压缩)
题目链接题目:思路:这个就类似最大子序列,有人会问,这和最大子序列有关系???,其实在我们进行矩阵压缩后,这个问题其实就变成了最大子序列矩阵压缩:我的理解就是把矩阵分成小的矩阵(把每种情况都分出来)。例我们有矩阵:1 2 34 5 67 8 9我们先枚举第一行 1 2 3.再加上的第二行 1 2 3 和 4 5 6再加上第三行 1 2 3 和 4 5 6 和 7 8 9再枚举第二行 4 5 6再加上第三行 4 5 6 和 7 8 9再枚举第三行 7 8 9这样做有什么意思呢原创 2020-05-23 21:34:29 · 416 阅读 · 0 评论