poj 2533(最长上升子序列)(n^2 ) 和 nlogn的算法

来源:互联网 发布:数据库王珊第四版pdf 编辑:程序博客网 时间:2024/05/18 10:38

题目链接:点击打开链接

题目大意:略

题目分析:1.用n平方的做法,枚举以data【i】为结尾的子序列,向前查找,比data【i】小并且dp【j】比dp【i】小的

新手代码:

#include<cstdio>#include<cstdlib>#include<iostream>#include<cstring>using namespace std;const int maxn=1005;int data[maxn],dp[maxn];int main(){    int n,i,j,ans;    while(~scanf("%d",&n))    {        for(i=0;i<n;i++)          scanf("%d",&data[i]);        ans=1;        for(i=0;i<n;i++)        {   dp[i]=1;//注意!!            for(j=i;j>=0;j--)              if(data[j]<data[i]&&dp[j]+1>dp[i]){dp[i]=dp[j]+1;}            if(dp[i]>ans) ans=dp[i];        }        printf("%d\n",ans);    }    return 0;}

测试样例

5

1 2 1 4 1

6

1 1 2 2 1 1

6

1 6 2 3 7 5


2. 二分法nlogn+栈+替换 参考:点击打开链接

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>using namespace std;const int maxn=1005;int stack[maxn];int main(){    int n,i,top,data,j;    while(~scanf("%d",&n))    {        top=0;stack[0]=-1;//注意栈首        for(i=0;i<n;i++)        {            scanf("%d",&data);            if(data>stack[top]) stack[++top]=data;            else            {                int l=1,r=top,mid;                while(l<=r)                {                   mid=(l+r)/2;                   if(data>stack[mid])  l=mid+1;                   else  r=mid-1;                }                stack[l]=data;            }        }        printf("%d\n",top);    }}

备注:这种方法适用于求数目,没有真正求出具体的字串

除此之外:其实不用栈

使用函数lower_bound()

函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置

举例如下:

一个数组number序列为:4,10,11,30,69,70,96,100.设要插入数字3,9,111.pos为要插入的位置的下标

pos = lower_bound( number, number + 8, 3) - number,pos = 0.即number数组的下标为0的位置。

pos = lower_bound( number, number + 8, 9) - number, pos = 1,即number数组的下标为1的位置(即10所在的位置)。

pos = lower_bound( number, number + 8, 111) - number, pos = 8,即number数组的下标为8的位置(但下标上限为7,所以返回最后一个元素的下一个元素)。

所以,要记住:函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置,且last的位置是越界的!!~

返回查找元素的第一个可安插位置,也就是“元素值>=查找值”的第一个元素的位置

关于lower_bound() 详见:点击打开链接

#include<stdio.h>#include<string.h>#include<algorithm>#define max 10005using namespace std;int main(){    int data[max],a[max],n,i;    scanf("%d",&n);    for(i=1;i<=n;i++)    {    scanf("%d",&data[i]);    }    int top=0;a[top]=-1;    for(i=1;i<=n;i++)    {        if(data[i]>a[top])        a[++top]=data[i];        else        {            int pos=lower_bound(a+1,a+1+top,data[i])-a;            a[pos]=data[i];        }    }    printf("%d\n",top);    return 0;}