最长上升子序列(LIS)
朴素dp(O( n 2 n^2 n2))
- 状态表示:
- 集合dp:所有满足上升条件的元素集
- 属性:cnt,dpi表示以i结尾的上升子序列长度,init(dp)=1
- 状态计算:
- i为当前工作区间尾指针,j为当前工作区间工作指针
- 不选i:aj>ai,无法满足最优解,不选
- 选i:aj<ai,满足上升条件,可选
- dpi的结果转移自dpj,因此转移方程为 d p i = m a x ( d p i , d p j + 1 ) dpi=max(dpi,dpj+1) dpi=max(dpi,dpj+1),当 d p i = d p j + 1 dpi=dpj+1 dpi=dpj+1时,说明ai已选,否则证明aj包含在之前已选的子集中
cpp
extern vector<int>v(n),dp(n,1);
int dp(){
for(int i=0;i<n;i++)
for(int j=0;j<i;j++)
if(v[j]<v[i])//选v[i]
dp[i]=max(dp[i],dp[j]+1);
return *max_element(dp.begin(),dp.end());
}
LCS求解LIS(O( n 2 n^2 n2))
思路:将序列排序,两序列的LCS即为原序列的LIS