最长上升子序列(LIS)
朴素dp(O( n 2 n^2 n2))
- 状态表示:
- 集合dp:所有满足上升条件的元素集
- 属性:cnt,dp[i]表示以i结尾的上升子序列长度,init(dp)=1
- 状态计算:
- i为当前工作区间尾指针,j为当前工作区间工作指针
- 不选i:a[j]>a[i],无法满足最优解,不选
- 选i:a[j]<a[i],满足上升条件,可选
- dp[i]的结果转移自dp[j],因此转移方程为 d p [ i ] = m a x ( d p [ i ] , d p [ j ] + 1 ) dp[i]=max(dp[i],dp[j]+1) dp[i]=max(dp[i],dp[j]+1),当 d p [ i ] = d p [ j ] + 1 dp[i]=dp[j]+1 dp[i]=dp[j]+1时,说明a[i]已选,否则证明a[j]包含在之前已选的子集中
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