动态规划:(dynamic programming)
知识点:枚举(状态)+递推(状态转移方程)
1.最长不下降子序列(LIS)
对于给定序列S={a1,a2……,an}
有一个子序列满足ai1<=ai2<=ai3……的最长序列
DP方程
设f[i]为前i个数中的最大不下降子序列的长度
则f[i]=1(i=1)
f[i]=max{f[j]+1},当j<i且aj<=ai
PS:最长不上升子序列
则f[i]=1(i=1)
f[i]=max{f[j]+1},当j<i且aj>=ai
2.最长公共子序列
对于两个序列A=(a1,a2……,an),B=(b1,b2,……,bn)
存在C=(c1,c2,……,ck)
满足c1=ai1=bj1,c2=ai2=bj2……
存在最长的C,则该C称为A和B的最长公共子序列
DP方程
f[i,j]表示A的i位和B的j位之前的最长公共子序列的长度
f[i,j]=0 (i=0 or j=0)
f[i,j]=max{f[i-1,j-1]+same(i,j),f[i-1,j],f[i,j-1]}(i!=0 and b!=0)
same(a,b)当A的第a位和B的第b位完全相同的时候位1,否则为0
PS:NOIP2004提高组,合唱队列
枚举i,求一个1-i最长不下降子序列的长度B[i],i-n的最长不上升子序列长度C[i],子序列中的数的大小均不超过第i个数字的大小
合唱队列的最大长度K=max{B[i]+C[i]-1}
背包问题(详见背包九讲)
3.01背包问题(棋盘动态规划)
题型:有N件物品和一个容量为V的背包。第i件物品的体积是c,价值为w
求解在体积总和不超过背包容量时价值总和最大。
每种物品仅有一件,可以选择放或不放
问题分析:
f[i,j]表示前i件物品恰好放入一个容量为j的背包所能取到的最大价值
f[i,j]=0 (i=0 or j=0)
f[i,j]=f[i-1,j] (j<c[i])
f[i,j]=max{f[i-1,j],f[i-1,j-c[i]]+w[i]}
完全背包:有N重物品和一个容量为V的背包,每种物品都有无限件可以使用,第i件物品的费用是c[i],价值是w[i]
求解将哪些物品装入背包使可以在不超过背包总量的情况下使价值总和最大。
状态转移方程:
F[i][j]表示前i种物品中选取若干件物品放入剩余空间为j的背包中所能得到的最大价值
F[i][j]=max(F[i-1][j-k*C[i]]+k*W[i]),0<=k*C[i]<=j
其中F[i-1][j-K*C[i]]+K*W[i]表示前i-1种物品中选取若干件物品放入剩余空间为j-K*C[i]的背包中所能得到的最大价值加上k件第i种物品;
设物品种数为N,背包容量为V,第i种物品体积为C[i],第i种物品价值为W[i]。
与01背包相同,完全背包也需要求出NV个状态F[i][j]。但是完全背包求F[i][j]时需要对k分别取0,…,j/C[i]求最大F[i][j]值,耗时为j/C[i]。那么总的时间复杂度为O(NV∑(j/C[i]))
4.石子合并(环形动态规划)
题型:在一个圆形操场的四周摆放着n堆石子,现要将石子有次序地合并成一堆
规定每次只能选择相邻的两堆石子合并成新的一堆,病且将新的一堆石子数记该次合并的得分
求n堆石子合并的最大得分
问题分析:
f[i,j]表示将第i堆石子到第j堆石子合并成一堆所能得到得到的最大得分
sum[i,j]表示第i堆石子到第j堆石子的石子总数
f[i,j]=0 (i==j)
f[i,j]=max{f[i,k-1]+f[k,j]}+sum[i,j]
5.树形动规
6.DAG上的动态规划