LIS
1 两重循环 每次记录是这个数本身长 还是找上一个+1长
for(i=0;i<n;i++)
{
scanf("%lld",&q[i]);
sum1[i]=1;
for(j=0;j<i;j++)
{
if(q[i]>q[j])
sum1[i]=max(sum1[j]+1,sum1[i]);
}
}
2 用一个数组记录答案 如果比上一个大就加进去 如果比上一个小在答案数组里找比它大的和比他小的 将比他小的替换
注意 这样找的是最长的但是答案数组里存的不是最后答案
for(i=1;i<=n;i++)
{
if(q[i]>dp[len1])
dp[++len1]=q[i];
else
{
pos=lower_bound(dp,dp+len1+1,q[i])-dp;//lower_bound();是在单调数组里找你要找的q[i]在哪 并返回指针
dp[pos]=q[i];
}
}
最长公共子序列LCS
类似于dp每次更新二维数组 看看代码 不好讲。。。。、
for(i=1;i<=len1;i++)
for(j=1;j<=len2;j++)
{
if(q[i-1]==w[j-1])
{
dp[i][j]=dp[i-1][j-1]+1;//如果一样 就把斜着打那个值加一
}
else
{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);//如果不一样 就将他上一行的和左边的取大的
}
}
回溯
while(dp[i][j]!=0)
{
if(q[i-1]==w[j-1])
{
ans[k++]=q[i-1];
i--;
j--;
}
else
{
if(dp[i][j-1]>dp[i-1][j])
j=j-1;
else
i=i-1;
}
}