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

   

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值