您的位置:首页 > 其它

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

2013-08-26 15:27 302 查看
题目链接:点击打开链接

题目大意:略

题目分析: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 10005
using 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: