首页 > 其他 > 详细

最长上升子序列 LIS

时间:2016-07-12 01:26:33      阅读:161      评论:0      收藏:0      [点我收藏+]

LIS是DP入门的一个基础题了

 

可以看这个,讲得很清晰

http://www.acmerblog.com/dp-3-longest-increasing-subsequence-4640.html

 

n^2模板:

/* LIS 的动态规划方式实现*/
/* lis() returns the length of the longest increasing subsequence in
    arr[] of size n */

int dp[MAXN],v[MAXN];

int n;

int lis()
{
   int i, j, ans = 0;

   /* Initialize LIS values for all indexes */
   for ( i = 0; i < n; i++ )
      dp[i] = 1;

   /* Compute optimized LIS values in bottom up manner */
   for ( i = 1; i < n; i++ )
      for ( j = 0; j < i; j++ )
         if ( v[i] > v[j] && dp[i] < dp[j] + 1)
         {
            dp[i] = dp[j] + 1;
            ans = max(ans,dp[i]);
         }

   return ans;
}

 

nlogn讲解:

http://www.acmerblog.com/lis-nlogn-4730.html

模板:

int n,top;

int stk[MAXN],v[MAXN];

void lis()
{
    top = 0;
    stk[0] = -1;
    for(int i=0;i<n;i++)
    {
        if(v[i]>stk[top])
        {
            stk[++top] = v[i];
        }
        else
        {
            int lo=1,hi=top,mid;
            while(lo<=hi)
            {
                mid = (lo+hi)>>1;
                if(v[i]>stk[mid]) lo = mid+1;
                else hi = mid -1;
            }
            stk[lo] = v[i];
        }
    }
}

 

此外还可以用lower_bound 函数,这个函数内部也是用二分查找

#include<stdio.h>
#include<string.h>
#include<algorithm>

using namespace std;

int num[10]={3,6,3,2,4,6,7,5,4,3};

const int INF=0x3f3f3f3f;
int l=10;
int g[100];
int d[100];
int main()
{
    fill(g,g+l,INF);
    int max_=-1;
    for(int i=0;i<l;i++)
    {
        int j=lower_bound(g,g+l,num[i])-g;
        d[i]=j+1;
        if(max_<d[i])
            max_=d[i];
        g[j]=num[i];
    }
    printf("%d\n",max_);
    return 0;
}

 

最长上升子序列 LIS

原文:http://www.cnblogs.com/qlky/p/5662150.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!