
动态规划
会飞的蟋蟀
学习中!!
展开
-
1.6.1 USACO Number Triangles
题解似乎是一道dp入门题目,想法就是 要求出最长的路径和, 那么直接将之前的路径上的长度取最长累加到目前的选择的路径上。 说起来有点绕,看看代码就很容易理解。 ( 但是我的代码为了省空间直接写成了一维的…代码/*PROG:numtriID:imking022LANG:C++ */#include <iostream>#include <cstdi...原创 2018-05-10 17:22:29 · 150 阅读 · 0 评论 -
USACO 3.1.2 总分 Score Inflation
题解完全背包裸题,不解释。Code// H F Eusing namespace std;int n,m,k;int f[10001];int v[10001],w[10001];int main(void){ cin>>n>>m; for(int i=1;i<=m;i++) cin>>v[i]>>w...原创 2018-09-10 15:49:17 · 369 阅读 · 0 评论 -
LeetCode 279. Perfect Squares
题解很多解法,包括不限于dfs,dp,甚至数学解法(最快)。给出dp解法dp [ i ] : 代表对 i 拥有的最少平方和数量。易得dp[ i ] = min{ dp[ i - k*k ] | k= 1,2,3… && k*k <= i }Codeclass Solution {public: int dp[10000]={0}; i...原创 2018-10-01 13:51:31 · 114 阅读 · 0 评论 -
LeetCode 416. Partition Equal Subset Sum
题解这题就是01背包,特征就是选与不选对吧。但是这题又有点变化,不是算max min 或者方案数,而是确定解是否存在,料想dp应为bool型。dp[ i , j ] : 代表在前i个数中,是否能取得和为j。转移方程很合理:dp [i , j] = d[ i-1, j ] || dp [ i-1, j - nums[i] ] // 取 或 不取ps: 注意dp[0 0] = true。显...原创 2018-10-02 11:32:18 · 131 阅读 · 0 评论 -
LeetCode 494. Target Sume
题解之前在luogu上做过一道类似的题,但是更难点还要考虑空格。记得也写过题解的但是找不到了。。。这道简化了点,所以我用dp来做一下,思路比较清晰。dp[ i , j ] : 表示前 i 个数组合成总和 j 的方案数有转移方程:dp[ i , j ] = dp[ i-1 , j - nums[i] ] + dp[ i-1 , j + nums[i] ]这很显然吧。注意j不能为负数,所...原创 2018-09-27 10:24:23 · 112 阅读 · 0 评论 -
LeetCode 96. Unique Binary Search Trees
题解这是一道很有意思的dp题目,值得玩味。给出一个写的很好的英文题解。解释得非常清楚。点几个要点:以不同序号标记去重,形成1-(i-1) – i – (i+1)-N的树形。G(N), F(i , N)的表示意思及联系。为什么 F(i , N) = G(i-1) * G(N-i)。Codeclass Solution {public: int dp[200]; // ...原创 2018-09-27 11:07:18 · 107 阅读 · 0 评论 -
LeetCode 221. Maximal Square
题解这道题在luogu上遇过,还有更烦人的类型比如算对角长度的。dp解之,比较简单 大体思路就是dp[i,j]代表以[i,j]为右下角的方块长度然后根据dp[i-1,j-1]和两边长度,遍历计算即可。Codeclass Solution {public: int maximalSquare(vector&lt;vector&lt;char&gt;&gt;&amp; matri...原创 2018-10-05 11:24:35 · 199 阅读 · 0 评论 -
LeetCode 55. Jump Game && 45. Jump Game II
题解LeetCode 上这种题目的变形非常多。因为比较相似这次两题一起写,思路比较连贯一点。第一题 55. mid 难度。这题只要判断能否到达尾部。我们用一个变量cur_max记录可到达的最远位置,遍历数组即可。注意此处出现的span数组,意为在i处时能到达的最远位置,这是此题的关键。第二题 45. hard。 也不难,算最小步长,但是测试用例里有一个case卡时间。最小最大,很明显是...原创 2018-10-06 10:38:17 · 157 阅读 · 0 评论 -
LeetCode 309. Best Time to Buy and Sell Stock with Cooldown
题解注意这道dp题对选择和状态的描述。用buy sell rest, 三个数组分别表示在 第i天时 能获得的最大收益。有转移方程: buy[i] = max( rest[i-1]-prices[i], buy[i-1] ) sell[i] = max( buy[i-1]+prices[i], sell[i-1] ) re...原创 2018-09-28 10:35:25 · 123 阅读 · 0 评论 -
LeetCode 152. Maximum Product Subarray
题解连续子序列最大乘积。和最大连续和有点相似,但差别明显。大概也会用dp[ i ] 代表以 i 为终点的最大积?不行因为数列中有负数,负数会瞬间改变前一位的最大积使之变最小。观察到最大最小的这种即时变化,所以我们要把两者都进行记录。cur_max = max( max( cur_max*nums[i], cur_min*nums[i] ),nums[i] );cur_min = min...原创 2018-10-06 11:58:37 · 271 阅读 · 0 评论 -
LeetCode 62. Unique Paths
题解很常见的矩阵位移类的dp,naive的做法是开个同大小的dp[m , n],然后 dp[ i , j ] = dp[ i-1 , j ] + dp[ i , j-1 ]。这样空间开销比较大,注意到dp[ i , j ] 的更新只依赖于上和左,那么其实用两行数组就可以。其实还可以优化到一组: dp[ i ] += dp[ i-1 ],哈哈Code不给了太简单...原创 2018-09-28 11:01:05 · 93 阅读 · 0 评论 -
LeetCode 576. Out of Boundary Paths
题解这道题我觉得难在内容理解,怎么程序表述出这样的一个目的。一开始我想了个bfs的,我想是从起点算移动到某位置时还剩下多少步数,如果剩余步数大于0而该位置在边界上那么该位置+1,最后遍历四周边界位置累加其数字即可。思路正确但是爆内存(剪枝一样爆),而且有点不是很透彻的感觉。看了下dp的题解,觉得舒服多了。三维dp[ i, j , k]:代表从i-j开始走k步能走出界的方法数。这个描述...原创 2018-10-18 15:53:30 · 148 阅读 · 0 评论 -
LeetCode 714. Best Time to Buy and Sell Stock with Transaction Fee
题解类型这里有一篇极尽完美的足以秒杀所有 stock buy&sell 类型的题解,写的非常完善。给出我觉得重要的点:T[ i, k, b ] 表示到i位为止交易k次情况下 是否(b=0 or 1)持有股票时获得最大收益边界条件T[-1][k][0] = 0, T[-1][k][1] = -InfinityT[i][0][0] = 0, T[i][0][1] = -Infi...原创 2018-10-19 11:13:11 · 119 阅读 · 0 评论 -
LeetCode 918. Maximum Sum Circular Subarray
题解最大连续子数组和大家都会做了,就一句话:cur_max=max(cur_max+nums[i],nums[i])这次是环型数组怎么办?想法一:两组首位拼成2n长的数组,再求最大连续和。可行否?可想法二:因为最大连续和可能在两组中间,求起来比较麻烦,但是转换一下这时最小连续和肯定在一个数组不会跨界,用总和-最小=最大和 bingo!!Codeint maxSubarraySu...原创 2018-10-26 12:51:53 · 425 阅读 · 0 评论 -
luogu P1736 创意吃鱼法
题解f [ i , j ] 代表以 i-j 为末端的最长值,显然依赖于f [ i-1 , j-1 ] 和 f [ i-1 , j+1 ] 即左上右上。 但左上右上可取到是有前提的,即左右上三个方向恰好有多于 f [ i-1 , j-1 ] 和f [ i-1 , j+1 ] 长度的空格。 那么我们用s1[ i , j ] s2[ i, j ] 来记录再 i-j 位 左右以及上方向有多少...原创 2018-09-12 15:23:41 · 113 阅读 · 0 评论 -
luogu P1095 守望者的逃离
题解这题我当作贪心来做了,看大佬们用dp用得很6啊,肥肠羡慕。本题核心思想: 在一段时间内移动尽可能多的位移,最大化时间效率。妥妥的贪心。大体思路:蓝充裕(m>=10)的时候肯定瞬移最快 60m/s,在蓝不够的时候有可能等回蓝再瞬移更快,也可能直接走更快。 这取决于剩余的时间。 代码中列了一个表,人肉算出来的是对 1-6s 时能够产生的最大位移。为什么只算到6s呢?因为以后的...原创 2018-09-12 13:20:59 · 131 阅读 · 0 评论 -
luogu P1052 过河
题解一道难点不在于dp的dp题目。转移公式很简单for( i = 1->n ) for( step = s ->t ) f[i] = min(self, f[i-step] + v[i])// v[i]:在i处有无石头我脑子比较抽用的max()来递推的,其实也一样。 但是这条路有 1e9 长,直接下去是肯定超内存又超时的,必须要想办法把无用的路...原创 2018-09-04 21:15:02 · 144 阅读 · 0 评论 -
luogu P1049 装箱问题
题解待写。。。代码#include &amp;amp;lt;iostream&amp;amp;gt;#include &amp;amp;lt;cstdio&amp;amp;gt;#include &amp;amp;lt;fstream&amp;amp;gt;#include &amp;amp;lt;cstring&amp;amp;gt;#include &原创 2018-05-30 20:31:16 · 116 阅读 · 0 评论 -
luogu P1057 传球游戏
题解用二叉搜索肯定是对的但是超时。这里给出一个dp的解法f[pos][t] = f[pos-1][t-1] + f[pos+1][t-1] pos: 位置 t: 步数 f[][]: 表示在此位此步存在的解法数代码#include <iostream>#include <cstdio>#include <cstdlib>usi...原创 2018-07-18 11:37:59 · 178 阅读 · 0 评论 -
luogu P1091 合唱队形
题解这道题有点意思,是一道有点变化的dp。这题的基础是那道最长递增序列。 简单的解题想法是对表中每位考虑 从左到此 最长序列多少,从此到右 最长序列多少。最后相加取最大值即可。代码#include <iostream>#include <cmath>#include <cstring>using namespace std;int n;...原创 2018-07-31 17:23:49 · 113 阅读 · 0 评论 -
luogu P1020 导弹拦截
题解这是一道需要加深理解才能ac的题目。 第一问 就是求最长非递减序列(倒序)的长度,用dp解很容易但是只有O(n),要优化到O(log n)需要一点高级的数据结构帮忙。 第二问 想了很久 发现用naive的屡次去除最长序列的方法失败。看了下大佬的解答, 发现了一个全新的定理 DilworthDilworthDilworth定理。这是一个离散数学里的知识点。 大意是讲 在一个偏序集合中...原创 2018-08-10 16:58:25 · 193 阅读 · 0 评论 -
USACO 2.2.2 集合 Subset Sums
题解仔细想一想就会发现这是一道dp,还是01背包类型的,是求方案数的。 看似是把数列分组,但是可视作把 N 个 重量分别为 1-N 的物体放入总重一定的背包中,且刚好放完的方案数计算。 递推式不难得出: f[i+1][j] = f[i][j] if ( i >...原创 2018-08-07 15:27:53 · 515 阅读 · 0 评论 -
luogu P1140 相似基因
题解这题和那道经典的最长相同子序列很类似,是一道简单的(?)线性dp。 仔细思考一下什么是状态,选择以及相互之间的影响。 F [ i ] [ j ] : 代表 i,j 位置为止的两段串的最大分数 转移方程 // 显然就3种选择 i,j配对 i不配对 以及 j不配对F [ i+1 ] [ j+1 ] = max{ ...原创 2018-08-22 10:57:04 · 152 阅读 · 0 评论 -
luogu P1880 [NOI1995]石子合并
题解第一次遇到区间dp的问题,这种解构问题的方法还是比较新颖的。 既然是dp,我们还是想要把全部的状态以及选择表达出来,怎样表示是个问题。大概思路是//mst(dp,0) 初始化DP数组for(int i=1;i<=n;i++){ dp[i][i]=初始值}for(int len=2;len<=n;len++) //区间长度for(int i=1;i&...原创 2018-08-22 14:29:37 · 276 阅读 · 1 评论 -
luogu P1282 多米诺骨牌
题解线性dp,需要一点理解。可以类比背包问题,此时的状态不是背包容量而是差值。 f [i][j]:代表对前 i 个牌在 j 的差值下 最小的翻动数。 有递推式 f [ i ] [ j ] = min( f [ i - 1 ] [ j - (a[i]-b[i]) ]+1 , f [ i - 1 ] [ j - (b[i]-a[i]) ] ) a[],b[] 为上下牌面数ps: 显然 ...原创 2018-08-17 19:47:09 · 140 阅读 · 0 评论 -
USACO 2.3.2 奶牛家谱 Cow Pedigrees
题解这道题你想模拟建树的方法来做是肯定行不通的,有高度有节点数,两种限制,有点背包的意思。 F [ i , j ] 代表有 j 个节点 i 层的树 的表示数量 显然每棵树都可分为根节点和左右两子树,我们只需让左右子树的最高高度为 i-1 以及其节点和为 j-1 就好了。 这样的情况只有三种: 1. 左右子树高度均为 i - 1 2. 左子树高度为 i - 1 , 右子树高度小于 i...原创 2018-08-30 17:23:05 · 312 阅读 · 0 评论 -
luogu P1233 木棍加工
题解这道题很像之前做过的导弹拦截的题目,关键点是偏序集。 显然答案就是这个二维数集合的最少链划分数,也就是最大的反链长度 (根据Dilworth定理)。 但是直接求反链还是难。 咱们先对其中一维由小到大排序,再对另外一维被固定的数,考察其非降序情况即可。 我看了一些贪心的做法也是可行的。ps: 再次出现 bus error。 在sort()中必须要用严格升序,参见std::sort...原创 2018-08-27 20:21:25 · 250 阅读 · 0 评论 -
USACO 2.3.3 货币系统 Money Systems
题解完全背包问题,讨论的是放完的方案数,只要把各种情况加起来就好了。 我给了一个2维空间的答案比较直观,可以压缩到一维,但需要推一下公式。Code// head files excludedusing namespace std;int n,m,k;long long f[2][10002];int cot[26];int main(void){ cin&g...原创 2018-08-31 12:10:04 · 278 阅读 · 0 评论 -
luogu P1006 传纸条
题解一道矩阵dp的升级版,难在来回两次怎么办? 想想可知来回其实就等价于走两次,怎样表示走两次呢?这又是个问题。 走一次的所有阶段和状态可以由二维数组解决,那么两次是不是可以用四维数组搞定呢。没错就是这么暴力。 定义 F [ i , j , k , q ] 为 第一走到[ i , j ] 第二走到[ k , q ] 时最大的积累值那么就有状态转移方程 F [ i , j , k ,...原创 2018-08-24 11:36:49 · 148 阅读 · 0 评论 -
luogu P1541 乌龟棋
题解难得做出一道dp题,虽然方法不是最好的,但记录一下思路,方便和大佬的比较一下。 这题有点像背包,但不一样的地方在于 背包问题中背包的价值和放的位置无关,本题中顺序会影响其价值。 显然所有的顺序都要被考虑。 这里简要给出我的思路: 设有 F [ pos , i-j-k-t ] ,表示到达第pos位置时候以 i-j-k-t (四种卡片消耗数量)此情况 能够取得最大价值。 每到一个...原创 2018-09-04 14:58:17 · 106 阅读 · 0 评论 -
LeetCode 818. Race Car
题解记忆化搜索。这题显然可以化为子问题来考虑的。大体思路:不妨设dp[n]为到达n的最短代码注意可以直接A到且最短的位置为 1,3,7,15, … ,(2^n) -1显然要考虑的情况就是target位于 2^(n-1) -1 ~ (2^n) -1 之间怎么处理这个区间更进一步?两种方法。走到target的后头位置(2^n) -1,此时调头向后走那么还需要走的的最短步数恰好= ...原创 2018-11-06 15:08:56 · 325 阅读 · 0 评论