动态规划
文章平均质量分 84
动态规划
Cu1ii*
平凡的铁匠
展开
-
最长公共上升子序列(LCIS)
前置知识LCSLIS注意: 刚开始看这个问题的时候,第一反应是先求出LCS再求出LCS的LIS,事实上这是有问题的,我们并不能保证这么求出的LCIS是最长的,比如下面这个例子Examplea:7 1 5 6 4 2 7b:7 1 5 4 6 7 2按照递归的取“最长公共子序列”,取出:7 1 5 6 2此序列的“最长上升子序列”为:1 5 6 (len=3)但原序列的“最长公共上升子序列”为:1 5 6 7 (len=4)求解 设第一个串为a,第二个串为b原创 2021-02-06 03:48:45 · 3277 阅读 · 1 评论 -
状压dp(自用)
状压dp:前言: 前几周遇到了状压dp的题,不会,所以学习了一下状压dp,本想着上一周写一篇博客,但是由于太忙 懒 ,这周补一下…1、位运算这部分摘取自 传送门名称符号运算法则举例按位与a&b两者同时为1则为1,否则为000101&11100=00100按位或a l b有1为1,无1为000101 l 11100=11101按位异或a^b相同为0,不同为100101^11100=11001按位取反~a是1为0,是原创 2020-12-09 21:54:41 · 237 阅读 · 0 评论 -
找零
题目链接思路: 这个题就是求能恰好构成 >= 给出钱数的最小值和最小硬币数量,且能支付的钱最少为第一优先级。 就是一个恰好装满的01背包问题dp[j] 表示 恰好能组成 j元钱所花费的最小硬币数求出dp数组后,我们从给出的价值V开始遍历,找到第一个 恰好能由硬币组成的且大于V的值,并将组成它的最小硬币数输出即可#include <bits/stdc++.h>#define ss system("pause");using namespace std;const int原创 2020-11-21 16:50:50 · 422 阅读 · 0 评论 -
捡苹果 (贪心 + 完全背包)
题目链接思路: 由于这个题目背包容量太大了,先不说会超时的问题,连dp数组都开不出来,所以我们要想办法减少背包容量,由此我们可以想到贪心。 我们先按照密度最大到小对三个苹果进行排序,然后分出两个空间,一个较小的空间和一个较大的空间,较大的空间我们直接用密度最大的填满(也可能会剩一部分空间,就把剩下的自动分配给较小的空间),然后对较小的部分进行完全背包,这样就解决了背包容量过大的问题 但是要注意,利用贪心的时候,留出的这部分较小空间,不能太小举个例子:3个苹果;4 73 56 2容量 6原创 2020-11-21 16:39:03 · 1434 阅读 · 1 评论 -
Chemist’s vows
Chemist’s vows 题意: 输入一个字符串,如果这个字符串可以由元素周期表的元素组成,就输出YES,反之则输出NO思路: 其实这个题可以用dp做,确实刚开始做的时候没想到,之前倒是做过一个类似的,这类问题,我就先叫它状态dp吧 大名叫啥还真不知道dp状态dp[n] 表示前n个字符能否全部由元素周期表构成,如果可以就是true,反之为false那么我们就可以通过O(n)枚举的方法来得到状态转移方程dp[j] = (dp[j - 1] & (字符j是否为元素符号)) | (dp原创 2020-11-21 15:41:13 · 180 阅读 · 0 评论 -
01背包变式 要求恰好装满的01背包
先给出关于01背包恰好装满情况的的一篇文章,写的很好 传送门题目链接题意: KTV里面有n首歌曲你可以选择,每首歌曲的时长都给出了. 对于每首歌曲,你最多只能唱1遍. 现在给你一个时间限制t (t<=10^9) , 问你在最多t-1秒的时间内可以唱多少首歌曲num , 且最长唱歌时间是多少time (time必须<=t-1) ? 最终输出num+1 和 time+678 即可. 注意: 你需要优先让歌曲数目最大的情况下,再去选择总时长最长的.思路: 别看给的时间是1e9,因为每原创 2020-11-18 17:54:30 · 351 阅读 · 0 评论 -
小张的困惑 烟大校赛 01背包变式
题目链接 题目是中文的,就不再过多进行赘述了。 这个题有两种思路1、带剪枝的暴力搜索,就是我利用DFS去暴力搜索所有的选择,从中选出一个满足条件的数,剪枝则是采用是否超过N如果超过就比较完返回,其次就是由于序列1 3 4 和 4 3 1和 3 1 4是一样的,所以我们只需要找出所有单调递增的数列组合就可以了,所以每次递归的起点都是上一次递归的值 + 1,这里对于DFS不进行过多赘述code#include <cstdio>#include <iostream>#原创 2020-11-16 21:38:24 · 173 阅读 · 0 评论 -
背包问题
1、问题描述: 给N件物品和一个容量为C的包,每件的价值和重量分别为v[i]和w[i]且每件物品的数量为num[i] ,问怎么拿可以使得包中物品的价值最大其实这个问题和之前的01背包和完全背包比较类似,所以如果没有上面两个基础的话,可以先去看下01背包和完全背包。2、重复背包dp状态和过程1、先说下未经优化的最朴素的dp过程 我们只需要仿照完全背包的过程就可以,只不过第三层循环是每件物品的数量所以我们可以得到状态转移方程...原创 2020-11-14 09:39:59 · 398 阅读 · 0 评论 -
B - Fabricating Sculptures
题目链接:Fabricating Sculptures题意: 给定一个底座的列数,要求底座必须填满,且上层方块的组成不能出现凹槽的形状,问底层为n,共有m个方块的摆放方式有几种思路: 我们可以发现,每一层向上,所有的方块都必须是连续的且保持从上到下满足递减的顺序,那么我们可以得到先定义dp状态:dp[n,m] 以n为底层时剩余m个方块的摆放方式的数量那么可以得到递推公式如下dp[i,j] = i * dp[1,j - 1] + (i - 1) * dp[2,j - 2] ... (i -原创 2020-11-12 21:19:31 · 140 阅读 · 0 评论 -
分组背包
本篇参考自传送门问题 有N件物品和一个容量为V的背包。第i件物品的费用是w [ i ],价值是v[i]。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。思想 这个问题就转化为了每一组都可以有多种取法,但是只能取一个物品,也可以不取,则可以设 dp[i,j] 表示前i 组物品容量为 j 时的最大收益则状态转移方程为dp[k][j]=max(dp[k−1][j],dp[k−1][j−c[i]]+w[i]∣物品i属于原创 2020-11-10 14:09:51 · 173 阅读 · 0 评论 -
Balls poj3783(dp,最坏情况最优解)
poj3783 Balls题意: 有一些鸡蛋,我们现在想知道这些鸡蛋的硬度。然后现在有一座很高很高的大楼里,我们现在要在这座大楼上测试鸡蛋的硬度。每个鸡蛋的硬度相同,鸡蛋的硬度定义为:如果鸡蛋从第 m 层上掉下来没有破裂,而从第 m+1 层上掉下来就破裂了,那么这个鸡蛋的硬度就是 m 。某个鸡蛋如果在实验中破裂了就永远的损失了。我们现在有 n 个鸡蛋。那么在最坏情况下我们最少需要做多少次实验呢?思路: 这是一个很经典的dp问题,设dp[n,m]是第i层楼,有k个鸡蛋时找到符合条件的最少测试次数原创 2020-10-31 21:00:32 · 1563 阅读 · 5 评论 -
ICPC模拟选拔 Greater New York Regional 2009 (补题)
文章目录ICPC模拟选拔 Greater New York Regional 2009 (补题)该题解参考并转自https://blog.csdn.net/u013050857/article/details/45080467**C**:[poj3783](http://poj.org/problem?id=3783)**D** : [poj3748](http://poj.org/problem?id=3784)题意:思路:代码:**F** :题意:思路:代码ICPC模拟选拔 Greater New原创 2020-10-25 21:51:06 · 165 阅读 · 0 评论 -
2020牛客国庆集训派对day4(补题)
2020牛客国庆集训派对day4B题意: 题意:求最长等差序列的长度。DP:摊派了我讲不明白,参考下这两篇博客吧(捂脸)传送门1传送门2#include<cstdio>#include<iostream>#include<queue>#include<set>#include<algorithm>#include <cstring>#include <string>using namespac原创 2020-10-04 21:47:50 · 1008 阅读 · 4 评论 -
数位dp
title: 数位dp数位dp文中提到的引用均来自巨佬数位dp,一般是求一段区间内满足给定条件的数的个数,数位:顾名思义,就是按照一个数的位数进行dp,比如一个三位数,就按照百位、十位、个位进行。但是我感觉,有些带记忆的dfs内味了数位dp实质还是一种暴力枚举的方法对于区间 [l,r] 求满足条件的数的个数,最简单的暴力做法如下:for(int i = l; l <= r; i++){ if(fair(i)) ans++;}但是这样如果l 是1而r是1e9,这种暴力的做.原创 2020-09-27 12:36:25 · 181 阅读 · 0 评论 -
RMQ (模板)
RMQ是查找区间最小或者最大值的问题一般有三种1、暴力2、线段树进行区间维护3、就是主要说一下dp的解法这种操作可以说是一种预处理,我们要求一个区间[L , R ] 的最大值,就把这个区间从中间劈开,求两个区间的最大值然后比较,就这样一直分解,直到区间长度为1那么也就是这个区间最大的是它...原创 2020-09-08 21:36:01 · 264 阅读 · 0 评论 -
补 ICPC Arab Collegiate Programming Contest 2013 I. Omar Loves Candies(dp)
I. Omar Loves Candies原创 2020-07-23 02:48:52 · 186 阅读 · 0 评论 -
补 UCF Local Programming Contest 2014 E. Pac Man for your New Phone
题目链接(万一以后能交了呢)E. Pac Man for your New Phone原文链接传送门因为计蒜客这个比赛到目前为止不能再交了,所以查看博友题解后,因为我那惨不忍睹的第一遍的打敲码正确率,不知道没有oj检验,我代码会怎么错,所以果断选择转载,当时不知道只能往右和下走,还在考虑是不是跟bfs求最短路相似,,看到博友文章后发现,恩,dp真香1000ms262144KYou are writing an app for your friend’s new Phone, the newPh转载 2020-07-20 19:39:55 · 964 阅读 · 0 评论 -
完全背包
这个问题和01背包问题类似,不同点在于完全背包问题中的物品可以取无数次.显然,我们可以把取多次同意物品的过程当作又增加了新的物品可以放入,这样就将其转换为01背包问题但是时间复杂度会非常大其状态转移方程为:> dp[i + 1][j] = max(dp[i][j], dp[i][j - k * A[i]] + k * V[i])for (int i = 0; i < n; ++i) for (int j = m; j >= 0; --j) for (in原创 2020-07-05 14:33:46 · 158 阅读 · 0 评论 -
01背包例题(持续更新。。。)
对于01背包不太熟悉的,可以先看下这篇文章传送门1、hdu2602,没啥好说的,就是基本的01背包问题但是可以进行空间优化,这里先直接给出二维数组的代码#include <iostream>#include <cstring>#define MAXN 1005using namespace std;int dp[MAXN][MAXN],v[MAXN],w[MAXN];int main(){ int t; cin>>t; whi原创 2020-05-29 02:23:28 · 363 阅读 · 0 评论 -
总结——01背包问题 (动态规划算法)
0-1 背包问题:给定 n 种物品和一个容量为 C 的背包,物品 i 的重量是 wi,其价值为 vi 。问:应该如何选择装入背包的物品,使得装入背包中的物品的总价值最大?分析一波,面对每个物品,我们只有选择拿取或者不拿两种选择,不能选择装入某物品的一部分,也不能装入同一物品多次。解决办法:声明一个 大小为 m[n][c] 的二维数组,m[ i ][ j ] 表示 在面对第 i 件物品,且背包容量为 j 时所能获得的最大价值 ,那么我们可以很容易分析得出 m[i][j] 的计算方法,(1). j转载 2020-05-27 19:51:08 · 520 阅读 · 0 评论 -
最大字段和(dp)
设a【i】,dp【i】我们在选择一个元素a[j]的时候,只有两种情况,将a[i]至a[j-1]加上,或者从a[j]以j为起点开始。我们用一个数组dp[i]表示以i为结束的最大子段和,对于每一个a[i],加上dp[i-1]成为子段,或以a[i]开始成为新段的起点。因为我们只需要记录dp值,所以复杂度是O(n)。如果不用求最大子段和的起始和终止位置,可以进行空间优化模板题51nod1049//最大字段和dp#include <iostream>#define MAXN 50000原创 2020-05-22 03:06:52 · 558 阅读 · 0 评论 -
最长上升子序列 Lis算法 + 例题
先留一篇很好的文章,下面只是为了加深印象所记录的一个例题,以及一些自己的总结传送门这里再加一种方法,就是再开一个数组,将原理的数组复制进去后,按升序进行排序,求这两个串的LCSO(n^2)朴实双循环的模板#include <iostream>#include <algorithm>#include <string.h>#define MAXN 1000+5#define INF INT_MAXusing namespace std;int dp[原创 2020-05-20 02:55:33 · 326 阅读 · 0 评论 -
dp基础 矩阵连乘问题,石头合并问题
题目描述:矩阵{A1,A2,…,An},其中,Ai与Ai+1是可乘的,(i=1,2 ,…,n-1)。用加括号的方法表示矩阵连乘的次序,不同的计算次序计算量(乘法次数)是不同的,找出一种加括号的方法,使得矩阵连乘的次数最小。先给出一位博主写的一篇很好的文章,传送门下面的文字只是蒟蒻的为了加深记忆和日后回顾所写的个人理解这里我们要先知道 :A m * n和B n * k的乘法运算次数为:m * n * k以A1 A2 A3三个矩阵相乘为例,乘法的顺序可以是 (A1 * A2)* A3或者是A1*(A2原创 2020-05-18 16:48:52 · 361 阅读 · 0 评论 -
dp最长公共子序列 (lcs)(不定期更新)
对于什么是子序列和公共子序列,这里不再进行赘述,直接切入主题。首先遇到这类问题,可能会首先想到穷举进行毕竟,但是穷举出一个长度为n的串的子序列,有2的n次方种情况,那么对于时间复杂度将会是指数级的,所以需要用dp的思想进行求解。我们先设两个字符串A,BAx为前x个连续字符组成的子序列,同理可得by的含义。那么比较Ax和By的最后一个字符ax和by情况一:ax == by那么ax和by一定是Ax和By的最长公共子序列的最后一个字符,所以我们只需要求LCS(Ax - 1,By - 1)的最长公共子序原创 2020-05-14 18:27:58 · 380 阅读 · 0 评论 -
牛客21302 被三整除的子序列(dp)
题目链接思路:易知,若要被三整除必须各位数字之和为3的倍数。可以将原问题分解为子问题的和进行解决,从底自上,将字符串的数字都对三求余转化为0 、1、2。设置一个dp数组存储前 i 位数字之和有几种情况对3求余为0,1,或2。切可以发现,当输入第 i 个数时 (1) 若 该数对3求余 == 0 那么前 i 个数中对3 求余为0 的组合为 dp[0] + dp[0] + 1,其余两种情况分别...原创 2020-03-16 15:58:41 · 353 阅读 · 0 评论 -
poj 1163 The Triangle (dp入门)
题目链接 The Triangle图片引用自,传送门1、自上向下的递归方法:首先,我们需要用二维数组去存三角形,这里先定义 MaxSum[MAXN][MAXN](每个点的最大值),d[MAXN][MAXN] (存三角形)。我们自上向下看,可以得到一个dp的递推公式:MaxSum[i][j] = max(MaxSum[i + 1] [j],MaxSum[i + 1] [j + 1]) + d[i][j];从(i,j)点出发,无非就是走到(i + 1,j)(i + 1, j + 1)。那么对于n行原创 2020-05-13 20:23:25 · 160 阅读 · 0 评论