LIS(最长上升子序列) LCS (最长公共子序列)

 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;
    }
}

   

猜你喜欢

转载自blog.csdn.net/qq_41886199/article/details/81206124