NOIP的DP总结之经典模型.docx
- 文档编号:11033760
- 上传时间:2023-02-24
- 格式:DOCX
- 页数:11
- 大小:23.89KB
NOIP的DP总结之经典模型.docx
《NOIP的DP总结之经典模型.docx》由会员分享,可在线阅读,更多相关《NOIP的DP总结之经典模型.docx(11页珍藏版)》请在冰豆网上搜索。
NOIP的DP总结之经典模型
DP经典模型(母题总结)
content
L_S
免费馅饼
矩阵dp
双塔DP
石子合并
选课
数字三角形
打砖块
子矩阵
最大子段和
方格取数
Hanoi
数的划分
逆序对
最短回文串
硬币问题
形成非降序列的最少合并次数
L_S问题
LIS&LCS&LCIS
话说LCS有O(n*m)的算法,LIS也有O(n*m)的算法;
XX日,LIS被栈和二分优化了,复杂度变为了nlogn,
q[1]:
=a[1];top:
=1;
fori:
=2tondo
begin
ifa[i]>q[top]then
begin
inc(top);
q[top]:
=a[i];
end
elsebegin
l:
=1;r:
=top;
whilel begin mid: =(l+r)div2; ifq[mid]>a[i]thenr: =midelsel: =mid+1; end; q[l]: =a[i]; end; end; 于是n排列的LCS也被优化了,也达到了nlogn. nlogn的LCS: 设有序列A,B。 记序列A中各个元素在B 中的位置,用序列C存,求C的LIS即可。 LCS与LIS结合,于是有了LCIS,LCIS有n*m的算法。 代码如下: fori: =1tondo begin t: =0; forj: =1tondo begin ifa[i]>b[j]theniff[j]>tthent: =f[j]; ifa[i]=b[j]thenift+1>f[j]thenf[j]: =t+1; iff[j]>ansthenans: =f[j]; end; end; 解释可以参考资料里的某文档或XX文库。 变式训练: 导弹拦截,合唱队型,船,交错匹配,最高线段覆盖, 最大子段和 *1*一般的最大子段和: F[i]: =max{f[i-1]+a[i],a[i]} Ans: =max{f[i]} *2*元素不可重复计算的最大子段和(cwx吃面包): S[a]表示a到b不重复计算的子段和, F[a]表示s[a]出现过的最大值。 Pre[k]表示元素k上一次出现过的地方 Forb: =1tondo Begin Fora: =pre[w[b]]+1tobdo Begin S[a]: =s[a]+w[b]; F[a]: =max(f[a],s[a]); End; End; Ans: =max{f[a]} *3*最大M子段和 F[i,j]表示前i个数,i属于第j子段时的最大值。 G[I,j]表示前i个数,分了j个子段时的最大值。 F[I,j]: =max{f[i-1,j],g[i-1,j-1]}+a[i]; G[I,j]: =max{g[i-1,j],f[i,j]}. 空间可以优化。 反思: 状态的巧妙设计,互补设计。 M=2时另有做法: 顺做一次最大子段和x[i],到做一次最大子段和y[i], Ans: =max{x[i]+y[i+1]}. 枚举断点法,很实用! *4*长度限制的最大子段和 可用单调队列优化。 最大子段和 最大m子段和(——必做! ) (n<=106,m<=50,允许空间O(n)) 算法1: F[i,j]表示前i个数,i属于第j子段时的最大值。 F[i,j]: =max{f[i-1,j],f[k,j-1]}+a[i].(1<=k 过不了! 算法2: G[I,j]表示前i个数,分了j个子段时的最大值。 F[I,j]: =max{f[i-1,j],g[i-1,j-1]}+a[i]; G[I,j]: =max{g[i-1,j],f[i,j]}. 过不了! 算法3: 根据分析g(i,j)=max{g(i-1,j),f(i,j)}发现,g要么和前一个状态g(i-1,j)相同,要么和此时所得的数f(i,j)相同。 同样的,f(i,j)=max{f(i-1,j)+a[i],g(i-1,j-1)+a[i]}中,f-a[i]要么和前一个状态相同,要么和前一个最优解g相同。 所以,我们可以用一维数组来代替二维数组。 F[j]: =max{f[j],g[j-1]}+a[i]; G[j]: =max{f[j],g[j]}. 成功AC! 最大不重复子段和: cwx吃面包问题。 平方做法。 子矩阵问题 *1*最大01子矩阵 枚举下边界,利用悬线的观点,然后有两种做法: 路径压缩法和两次单调队列法。 其实还可以将不要的一方赋值为-oo,从而转化为*3*最大子矩阵问题。 *2*另外,最大01子正方形: f[i,j]: =min(f[i-1,j],v[i,j-1],v[i-1,j-1])+1; ans: =maxvalue(f); *3*最大子矩阵 枚举上下边界,化二维为一维(最大子段和问题)。 变式: *1*找一个矩阵,使得其中的1的个数减去0的个数最大,输出最大值。 方法: 将0变为-1,问题转化成最大子矩阵 *2*AHOI2007宝库通道 *3*最大面积 【题目描述】 已知一个大矩形的长和高l和w(1<=l,w<=10000),有n(n<=5000)个点在大矩形内部(包含边上),求大矩形内部边平行于这个大矩形且点都不在小矩形内的小矩形的最大面积(点在小矩形边上不算在小矩形里面)。 【输入输出】 输入文件第一行为整数l和w。 接下来一行为整数n。 接下来n行为这n个点的坐标整数x,y(0<=x<=l,0<=y<=w)。 输出文件为一个整数,即小矩形最大面积。 解析: 点数较稀的问题,可以另辟蹊径。 分三种情况: 某两端无限制,另两端限制;三端限制;四方限制。 可以先两遍Qsort再做。 *4*最大子立方体问题 枚举一组边i的起始,压缩进矩阵B[I,j]+=a[x,I,j] 枚举另外一组边的起始,做最大子矩阵 数字三角形 *1*朴素的数字三角形 f[i,j]: =max(f[i+1,j]+a[I,j],f[i+1,j+1]+a[i,j]); *2*数字三角形2晴天小猪历险记之Hill 同一阶段上暴力动态规划 if[i,j]: =min(f[i,j-1],f[I,j+1],f[i-1,j],f[i-1,j-1])+a[i,j] *3*数字三角形3小胖办证 f[i,j]: =max(f[i-1,j]+a[i,j],f[i,j-1]+a[i,j],f[i,j+1]+a[i,j]) 以上*2**3*用到二次dp。 三角蛋糕 剪围巾 方法: 枚举分割线。 过河卒: 求方案数的一般方法。 打砖块 朴素的打砖块 f[i,j,k]: =max(f[i-1,j-k,p]+sum[i,k],f[i,j,k]); 数字三角形6优化的打砖块 f[I,j,k]: =max{g[i-1,j-k,k-1]+sum[I,k]} 打砖块(模型转化) *1*曲线转化(mlj) *2*旋转转化 这样就变成了从每一行的开头连续取数,且第i层取的数字个数不能超过第i-1层取的个数+1。 这样就没有后效性了。 有子弹奖励的打砖块: 难! 应当不考? ! 最短回文串 有两种做法: 1-F[I,j]表示将s[I..j]变为回文串的最小代价, 方程如下: F[I,j]=f[i+1,j-1],s[i]=s[j] F[I,j]=min(f[i+1,j]+1,f[I,j-1]+1);s[i]<>s[j] F[i+1,j]+1表示在j后插一个字符 F[I,j-1]+1表示在i前插一个字符 2-将原串(a数组)与原串的倒序(b数组)做一次LCS,用原串长度减去LCS长度,即为需要插入字符的个数。 证明: 在a数组中加上b中与a不同的n-LCS个,在b数组中加上a中与b不同的n-LCS个,得到a与b完全相同。 (自己想想) 逆序对 *1*求逆序对个数: dp或树状数组或归并。 *2*逆序对个数为k的排列数: 排列dp: f[I,j]表示i排列中逆序个数为j的排列数, f[i][j]= 可以用前缀和优化 或者f[i][j]=f[i][j-1]+f[i-1][j]-f[i-1][j-i-1] 排序工作量之新任务 F[I,j]表示前i个数构成的全排列中,逆序对为j的方案数。 G[I,j]存储最佳方案。 复杂度O(n^5) 一些题 Poj10881276(**)1837106211601185 双塔DP(类差值问题): Poj1837balance,NOI2011嘉年华,LZN的team(分组),LDL的lines(排队),搭建双塔,任务调度(难)。 装箱问题 尽量均分的目标型DP: 先求half,转化为求容量为half的装箱问题。 题目: 挤牛奶,石子归并,补圣衣 滑雪 *1*原版: 水 *2*上下走(weakness): 转化为找两起点相同的单增的路。 先离散化,F[p,q]表示一条路到达高度为p,另一条路到达高度为q时的最长路经和。 形成非降序列的最少合并次数 给定一个序列,你每次可以合并相邻两个元素,新的元素为这两个元素的和。 你需要使得若干次合并之后的序列非降,求最小合并次数。 [LYP的并,tyvj2008tower,QW的CCL] 解析: 设f[i]表示以i结尾的所有数分成的组数,g[i]存第i个数结尾的数它这组的数的值,那么转移为: f[i]=max{f[j]+1}(j=g[j]),转移f[i]的同时转移g[i]为s[i]-s[j], 初始f[i]=1,g[i]=s[i]. 通过观察我们发现,设当前分了k组,第i个数,最坏分到第k组,所以,f数组一定是不减的,所以j只要倒着循环,找到第一个满足s[i]-s[j]>=g[j]的j,转移f[i]. 开始认为此方程有问题{存在p,使得f[p]在所有已得到的f值中最大;若存在q满足f[q] 但是这种情况不存在! f值单调非降! }, 另外有单调队列做法。 归纳总结: 类型1: 消值求积分。 (断点型) A.最少矩阵乘法次数 B.凸多边形的三角形划分 C.删字游戏 D.能量项链 E.石子合并 这类问题的通用方程为: F[I,j]=max(ormin){f[I,k]+f[k,j]+c[i]#c[k]#c[j]} 运算符#由题意决定 实现有三种: 记忆化、倒推、按长度推。 类型2: 数字串中添加加号(乘号),求最值。 A.最大乘积 B.最佳加法表达式 C.统计单词个数 D.数字游戏 这类问题的通用方程为: F[I,j,k]=max(ormin){c[I,s]#f[s+1,j,k-1]} 运算符#由题意决定 另一种写法: F[I,k]=max(ormin){f[j,k-1]#c[j+1,i]} 以上两种类型都有递归方程,可以递归解,也可以转非递归。 类型3: 尽量均分问题(装箱问题)。 题33……37,40。 方法: 先求half,转化为求V=half的装箱问题。 类型4: 类差值问题(也称目标型dp)。 这类问题,状态要记录一个差值。 长短互转的忘了是哪个题了。 。 A.多米诺骨牌 B.取模方案数 C.Poj1837balance D.搭建双塔 E.ProcesstheTasks(zoj3331,10年浙江省赛) (难)(AC) 这题方法: dp[i][j][x]表示当前处理完第i件任务后,两台机器的结束时间差为j时,最早的总结束时间。 x表示j的正负. 同样,这题也有3种转移: 1: 第N项工作加在较高的塔上,此时虽然高度差增加,但由于N+1项工作必须在第N项开始之后才能开始,因此在另一塔的高度也增加了空闲值。 exp: A: 20 B: 10 将第N项发任务放在A上后,A->30,而B中10-20那段时间变为不可用,因为题目条件3。 因此B的高度变到20。 也正因为如此,时间差 最多只到单件任务时间的最大值。 2: 第N项工作加在较低的塔上,使高度差减小,但原先的高塔仍然较高 3: 第N项工作加在较低的塔上,使低塔高度超过高塔 最后dp[N][0-max][0|1]中的最小值即为答案。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- NOIP DP 总结 经典 模型