随笔分类 - 记忆化&动态规划
摘要:Miku 从叶子结点开始,自下而上得跑分组背包 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int n,m; int s[301]; struct b{
阅读全文
摘要:Miku 或许dp起来有点麻烦 那何不记忆化呢 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; int head[100001
阅读全文
摘要:Miku 区间dp模板,记得longlong #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; long long n; long long a[201]; l
阅读全文
摘要:Miku 定义$f_$为到达(i,j)的最小代价 然后对于从下往上,因为可以点无数次,是个完全背包,从上往下就一次,01背包,飞到天花板上的,拽下来 水管特判 #include<iostream> #include<cstdio> #include<cstring> using namespace
阅读全文
摘要:Miku 仍然是要优化的,但是输出方案是非常恶心的 一维爆炸,以下为二进制优化做法 关键是如果最后到着找方案的话,就比如说样例 5的最少方法就是一个5,但是因为dp的顺序是逆序。会把10指向5,然后5指向0 、??,但是只有一个啊。所以不能倒序 #include<iostream> #include
阅读全文
摘要:Miku 多重背包板子 纯多重背包好想>\(dp[i]=max\{dp[i-k*w[j]]+k*v[j]\}\) 但是要优化。这里采用二进制优化。 二进制优化是啥呢,假如i物品有13个 13可以拆成1+2+4+6,然后用这四个,就可以表示除1-13所有可能了 这样就把多重背包优化成了01背包 #in
阅读全文
摘要:Miku 线性dp+单调队列优化 单独的线性dp很好想,也很好卡。需要用单调队列优化。 对于1~l-1的点,他们是不可能到达的,(当然还有,不过因此for从l开始)。初始化dp为一个大负数,因为有negative答案 然后从l~n枚举(这里是要算dp的点),画个图就很好理解,单调队列扫到的点和枚举的
阅读全文
摘要:链接:Miku hash?不不不,kmp走起 唯一的问题是最后要有一个dp来解决 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int n; const i
阅读全文
摘要:链接:Miku 这一个问题考虑为两种问题 1:剩下的砝码有什么情况? 2:能拼出多少种? 对于1:没有办法,只能爆搜所有情况 对于2:用一个改良的01背包就可以解决 #include<iostream> #include<cstdio> #include<cstring> using namespa
阅读全文
摘要:链接:Miku 这是一道背包,但是对于放东西有条件限制 首先思考,对于每一个物品,除非放不了,否则就要放,不放上就吃掉,肯定不能扔那不管 我们定义dp[i][j]为第i个物品,高度为j的时候能活的最长时间,那么整个转移过程就是 for(int i=1;i<=g;++i){ for(int j=0;j
阅读全文
摘要:链接:Miku 这道题还是个背包 首先看一下声音的组成,对于每一个农场的声音,它是由两部分组成的 :上一个农场的声音-1(如果有的话)+这个农场的声音(如果有的话) ,并且声音也之和上个农场的总声音有关(注意,总声音,上个)和这个农场,所以我们可以递推出每一个农场的声音。 那么每一个声音代表多少牛呢
阅读全文
摘要:链接:Miku 这就是一个完全背包的板子题 我们把重量当作重量,开销当作价值,那么这个题就是个求价值最小的完全背包 然而题目上说了是不少于,也就是说最优解不一定恰好就是买h磅的时候,怎么办呢? 只要多余h就行了的话,我们就在h+x的范围内找一个最小值不就可以了? 1 #include<iostrea
阅读全文
摘要:链接:Miku 这道题给了我一个惨痛的教训 虽然说我是被学信息学不用写字吸引的,但是做题必须证明,必须动笔证明! 本蒟蒻被绿题卡了3个小时有感 这道题最后写出来发现并不是怎么很难啊,为了无后效性,我们倒着搜索每一个任务,因为任务的特殊要求,我们开一个数组记录这个时候的 开始的任务数。对于每一个时间,
阅读全文
摘要:链接:Miku 这道题的dp还是先更新子节点,在更新父节点,不过问题就是怎样更新他们 我们定义ff[i][j]为第i个节点字数上共保留j条边的情况下最多的苹果数,对于每一个点,他保留的边必然是他直接保留的之前保留的边和他当前儿子保留的边的值的和加上这一条边的 边权,即ff[u][i]=max(ff[
阅读全文
摘要:链接:Miku 此文不是正解,而且主要内容都在代码和注释上 这是暴力分组背包做法 对于每一个主件及其附件,我们的选择是有限的,而且这道题中说了最多两个附件,那么 我们完全可以枚举每一种组合,然后组合成一件新的物品,并且属于同一个集合,然后对处理后的新物品们 跑分组背包就行了 #include<ios
阅读全文
摘要:链接:Miku 分组背包,我们只需要在01背包的基础上稍加修改,把同一类的物品同时枚举即可。 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int n,m;
阅读全文
摘要:链接:Miku 很入门的树形dp,首先,在这个题中,我们要做的就是求出来每一个子节点,然后用他们去更新父亲节点。 对于每一个节点,他有两种状态,去,或者不去,我们定义dp[i][0]为第i个节点也去的状态,而dp[i][1]为它不去,那么很显然 如果这个点去了,它的子节点肯定不去,那么dp[i][1
阅读全文
摘要:链接:Miku 这是一道dp题,我么很容易发现这点。 数据范围很大,如果直接用两个塔的高度当状态,很危险,我们就必须要考虑一下优化了。 两个塔的高度其实是没有没要的,我们追求的是差值,那么,比如6 8 和7 9,很明显,无论我们怎么放,第二个就是第一个加1,无论如何。 那么我们没必要存第一个状态的,
阅读全文
摘要:链接:Miku 这是一道01背包+二分 二分的部分很普通,至于check函数,也不过是忽略掉了所以比接口还大的物品而已 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace
阅读全文
摘要:链接:Miku 发现大家基本上都是令 > dp[ i ] [ j ] 为用前 i 种花,摆 j 盆的总方案数 然而本蒟蒻乱搞一通,搞出来了这个东西 >dp[ i ] [ j ] 为在第i个位置摆第j种花的总方案书 这样答案就是 dp[m][1-n]的和了 1 #include<iostream> 2
阅读全文