LIS:Longest Increasing Subsequence
int ans = 0;
for(int i=0;i<N;i++){
dp[i] = 1;
for(int j=0;j<i;j++)
if(A[i] > A[j])
dp[i] = max(dp[i] , dp[j] + 1);
ans = max(ans , dp[i]);
}
memset(dp , INF , sizeof(dp));
for(int i=0;i<N;i++)
*lower_bound(dp , dp+N , A[i]) = A[i];
cout<<lower_bound(dp , dp+N , INF) - dp<<endl;
LCS:Longest Common Subsequence
memset(dp , 0 , sizeof(dp))
for(int i=0;i<l.length();i++)
for(int j=0;j<r.length();j++)
if(l[i] == r[j])
dp[i+1][j+1] = dp[i][j] + 1;
else
dp[i+1][j+1] = max(dp[i+1][j] , dp[i][j+1]);
cout<<dp[l.length()][r.length()]<<endl;
- 滚动数组dp:注意为什么需要留下两维:必须先写矩形,再根据矩形优化到滚动数组
memset(dp , 0 , sizeof(dp));
int t = 0 ;
for(int i=0;i<l.length();i++){
t = 1 - t;
for(int j=0;j<r.length();j++)
if(l[i] == r[j])
dp[t][j+1] = dp[1-t][j] + 1;
else
dp[t][j+1] = max(dp[t][j] , dp[1-t][j+1]);
}
cout<<dp[l.length()%2][r.length()]<<endl;
- NlgN:记录位置,再NlgN做LIS,但是在重复元素较多时,一般并不能真正起到效果
int cnt = 0;
for(int i=0;i<l.length();i++)
for(int j=r.length();j>=0;j--)
if(l[i] == r[j])
F[++cnt] = j;
memset(dp , INF , sizeof(dp));
for(int i=1;i<=cnt;i++)
*lower_bound(dp , dp+cnt , F[i]) = F[i];
cout<<lower_bound(dp , dp+cnt , INF) - dp<<endl;