动态规划专题
标签: ACM
动态规划思想
- 动态规划问题是指可以将一个复杂的问题分解为若干个子问题,而子问题又可以分解成更子的问题(就像分割一样),通过最小的子问题的最优解一步一步往上,进而得到原问题的最优解
- 和分治的区别:两者都是分解得到子问题,通过子问题的解得到原问题的解,但是分治的子问题之间是互相不干扰的(像归并排序,左右序列在人脑中是可以同时进行的),而动态规划的子问题可能是相互依赖的(可能会相互用到)
最大连续子序列和
- 要求:严格连续,即下标不能像2,4,5…这样,而必须2,3,4,即2,4之间不能空一个a[3]
- 思想:枚举右端点,对于每一个数,要么自己一个人组队,要么和前一个数组队,而前一个数也是同样可以自己组队或者和前一个数组队。故解法为:确定边界+状态转移方程递推: d p [ i ] = m a x { a [ i ] , d p [ i − 1 ] + a [ i ] } dp[i]=max\{a[i],dp[i-1]+a[i]\} dp[i]=max{a[i],dp[i−1]+a[i]}因当前状态用到前一个状态的数据,故从左向右递推。
最长不下降子序列(LIS)
- 要求:下标可以不连续
- 思想:同"最大连续子序列和"枚举右端点,因下标可以不连续
。故解法:确认边界+状态方程递推 d p [ i ] = m a x { 1 , d p [ j ] + 1 } , ( j = 0 , 1 , 2... i − 1 & & a [ i ] > a [ j ] ) dp[i]=max\{1,dp[j]+1\},(j=0,1,2...i-1\&\&a[i]>a[j]) dp[i]=max{1,dp[j]+1},(j=0,1,2...i−1&&a[i]>a[j])
最长公共子序列(LCS)
- 要求:两个string a,b,下标可以不连续
- 思想:同样枚举两个右端点 i , j,dp[i][j]表示这两个端点之前的最长公共子序列 ,对于任意的i,j,
1. 当 a [ i ] = b [ j ] 时 , d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] + 1 1.当a[i]=b[j]时,dp[i][j]=dp[i-1][j-1]+1 1.当a[i]=b[j]时,dp[i][j]=dp[i−1][j−1]+1
2.
当
a
[
i
]
!
=
b
[
j
]
2.当a[i]!=b[j]
2.当a[i]!=b[j]于时,区间扩大,但是公共序列没有增大,继承
d
p
[
i
]
[
j
]
=
m
a
x
{
d
p
[
i
−
1
]
[
j
]
,
d
p
[
i
]
[
j
−
1
]
}
dp[i][j]=max\{dp[i-1][j],dp[i][j-1]\}
dp[i][j]=max{dp[i−1][j],dp[i][j−1]}
当前状态用到左边一个状态和上面一个状态,故递推顺序为从上往下,从左往右,即大循环(i=0,n),循环里面为(j=0,n)
最长回文子串
- 要求:一个字符串string a;
- 思路:i,j为左右端点,dp[i][j]=1表示这个区间为回文串,遍历两个端点i,j;
当 a [ i ] = b [ j ] 时 , d p [ i ] [ j ] = d p [ i + 1 ] [ j − 1 ] 当a[i]=b[j]时,dp[i][j]=dp[i+1][j-1] 当a[i]=b[j]时,dp[i][j]=dp[i+1][j−1]
当 a [ i ] ! = b [ j ] 时 , d p [ i ] [ j ] = 0 当a[i]!=b[j]时,dp[i][j]=0 当a[i]!=b[j]时,dp[i][j]=0
能确定的边界是”"对角线dp[i][i]和dp[i][i+1],没有那种i,j遍历方式能实现状态转移。考虑到dp[i][j]和dp[i+1][j-1]之间有长度的差异,故使用遍历左端点+长度的方式
for(int i=0;i<s.size();i++){//预处理len=1,2
dp[i][i]=1;
if(!i){
if(s[i]==s[i-1]){
dp[i-1][i]=1;
ans=2;
}
}
}
for(int len=3;len<=s.size();len++){
for(int i=0;i+len-1<s.size();i++){
int j=i+len-1;//右端点
if(s[i]==s[j]&&dp[i+1][j-1]){
dp[i][j]=1;
ans=len;
}
}
}
cout<<ans;
背包专题
01背包
- 要求:n件物品,重w[i],价值v[i],背包最大承重v
- 思路:很简单,一件物品可以拿也可以不拿,dp[i][j]表示前i件物品,在背包承重为j时能取得的最大值。可以转化为一维dp[j],遍历顺序同样画图可得出。
完全背包
- 分析同01背包和上面四种模型