
dp
文章平均质量分 74
Tekim
个人写点东西的地方
展开
-
洛谷p1880石子合并
原题每次合并相邻的石子,用搜索比较耗时,想想dp可不可以。合并后的石子不会产生后效性,那么假设有两堆已经是最优的石子堆,合并它们的代价就是其石子数之和,合并出来的一定是最优解,而你的目标是将所有石子合并成一堆,但问题是不知道其中最优的两堆是如何划分的那么引入k作为你目前合并成一堆的分割点,枚举k由左端点到右端点,找出最优解。但是本题要求石子放在圆形操场,即首位相连。想象一下原创 2017-08-25 20:08:04 · 462 阅读 · 1 评论 -
洛谷p1541乌龟棋
原题不能用贪心,那么就是线性dp,难点在于如何表示状态,因为牌的种类只有4种,所以开一个五维数组分别表示位置、不同牌的牌数即可。可以优化一维,因为牌的总数已知,m-3种牌数=另外一种牌的数量。我写的是递推式,因为牌数刚好用完,直接输出f[n][0][0][0]。#include#include#include#include#includeusing namespace st原创 2017-08-31 10:50:35 · 472 阅读 · 0 评论 -
洛谷p1970花匠
原题一共两种情况,分别画图模拟一下就可以很快想出思路,线性dp分情况讨论 ,波峰与波谷交替出现,比如现在正在求f[i],那么寻找i之前比他矮(那么他就是波峰)或比他高(他是波谷),取最大值存入,并且记录他是波谷还是波峰。代码不难实现,看懂思路就好。#include#include#include#include#includeusing namespace std;int原创 2017-08-31 10:42:52 · 377 阅读 · 0 评论 -
洛谷p2831愤怒的小鸟
原题每个猪的位置不同,所以不能简单的表示出状态,all[i]表示第i个抛物线打掉了哪些猪,其值本身存储状态(二进制),只需要找所有有用的抛物线,然后状压f[i]表示i状态下最少用掉的鸟,转移方程见代码。其中的m可以用来优化。代码虽然长,但是比较好懂。#include#include#include#include#include#includeusing namespace原创 2017-08-31 09:57:05 · 448 阅读 · 0 评论 -
洛谷p1052过河
原题先想一下思路,由于是区间跳跃,不能用贪心,那么f[i]表示跳到i时最少踩到的石子数,i只能由i-t~i-s转移过来,所以选择其中的最小值跳,保证f[i]最小。但是l太大了,1e9,但是m和t很小,就是1e9中有很多没有用的空间,我们求终点的值,所以中间废掉的空间可以省略,缩点之后用还能用单调队列优化一下。#include#include#include#include#in原创 2017-08-31 09:32:48 · 361 阅读 · 0 评论 -
洛谷p1879玉米田
原题看取膜的数就知道暴搜死定,那么用状压,f[i][j]表示可以转移到i行j状态的方案数,和互不侵犯类似,但由于提前有赋值,所以把1和0换一下可以更方便的判断推导。#include#include#include#include#include#includeusing namespace std;int m,n;bool a[14][14];int b[14],f[14]原创 2017-08-31 08:44:10 · 573 阅读 · 0 评论 -
洛谷p1896互不侵犯
原题先思考怎么表示状态,用f[i][j]表示第i行放j个显然不行,那么需要一个可以表示出状态的变量,由于m很小,可以用二进制表示每个位置是否放置,因此f[i][j][z]表示第i行放置状态j时共放置z个国王的方案数,本行只收上一行的状态。我用的是状压dfs,和状压dp想法一样,而且比较好实现,另外复杂度相同。状压dfs(((2^n)^2)*k*n)最坏情况1e9,可以ac。x表示行原创 2017-08-31 07:45:30 · 456 阅读 · 0 评论 -
洛谷p1156垃圾陷阱
原题每落下一个垃圾,有两个选择——吃掉或摞起来,摞到一定高度即可。那么状态很好表示,现在有三个元素,生命,高度,时间,任意两个表示状态可存入第三个。考虑哪一个最好,原创 2017-08-30 16:57:27 · 351 阅读 · 0 评论 -
洛谷p1387最大正方形
原题用搜索最坏情况小于1e10,一般不会超时。这里需要一个技巧,f[i][j]表示在i,j点的最大正方形变长,f[i][j]=min(f[i-1][j],min(f[i][j-1],f[i-1]))原创 2017-08-28 14:22:50 · 385 阅读 · 0 评论 -
洛谷p1006传纸条
原题不能每次选最大的走(贪心),因为有可能小的后面接大的,比如0 1 9912 10 1由于只能想两个方向走,所以到达结果的步数是固定的(长+宽-1)但是用步数不能表达状态,所以就用坐标表示f[i][j]表示在(i,j)最大的和,转移方程有反方向得来要求来回且路线不能重合,那么用f[i][j][k][z]表示第一次在(i,j),第二次在(k,z)的最优解虽然起始原创 2017-08-28 14:08:48 · 444 阅读 · 0 评论 -
洛谷p1063能量项链
原题和环形合并石子很像,没做过合并石子的推荐先去做它。这是石子合并的题解,这里就不多啰嗦了。#include#include#include#include#includeusing namespace std;int n,a[101],f[201][201],ans=0;int main(){ cin>>n; for(int i=1;i<=n;++i)原创 2017-08-27 20:05:59 · 371 阅读 · 0 评论 -
洛谷p1108低价购买
首先可以分析出来要求单调下降子序列,那么下一步需要求满足最长的数量且不能重复,那么思考一下,能不能在求出最长序列的同时求出满足此长度不相同的序列呢?(这种类型题和子字符串匹配比较类似,也是个人认为noip范围内最难的一种线性dp)满足两个条件,线性不会产生后效性,开一个数组记录,那么就从i位向前找,凡是满足条件的就加入,凡是遇见相同值且长度相同就将前面的数组清零,这样讲比较模糊,请结合代码思考。原创 2017-08-27 19:36:34 · 460 阅读 · 0 评论 -
洛谷p1280尼克的方案
实际上还是比较好想的,明显是线性,所以用一维f[i]表示i时最少工作时间;那么大致想一个思路,f[i]=f[i+time]+time,这样就自动忽略了此时新来的工作。根据转移方程,需要时间靠后的状态,所以倒着推,根据2,从开始的时间推。原创 2017-08-25 20:42:30 · 312 阅读 · 0 评论 -
洛谷p1064金明的预算方案
原题如果不考虑附件,就是一道01背包题。所以我们就先不考虑附件,把它当作01背包做一下;因为最多只有两个附件,每个物品的状态只有三种(没,有一个,两个),分别当作01背包做一下,即分为4个01背包。然后比较四个背包总的最大值。#include#include#include#include#include#includeusing namespace std;struct原创 2017-08-25 20:24:06 · 457 阅读 · 0 评论 -
洛谷p1005矩阵取数游戏
原题2^80超int,需要高精度计算,也可以int128.行和行之间没有联系,所以只要单独求每一行之后取和即可,dp过程中i,j分别表示左端点和右端点。#include#define lll __int128void print(lll x){ if (x==0) return; if (x) print(x/10); putchar(x%10+'0');原创 2017-08-31 11:11:29 · 557 阅读 · 0 评论