zoukankan      html  css  js  c++  java
  • HDU5748---(记录每个元素的 最长上升子序列 nlogn)

    分析:

    给一个序列,求出每个位置结尾的最长上升子序列

    O(n^2) 超时

    #include "cstdio"
    #include "algorithm"
    #define N 1005
    #define INF 0X3f3f3f3f
    using namespace std;
    int a[N];
    int dp[N];
    void solve(int n)
    {
        for(int i=0;i<n;i++)
        {
            dp[i]=1;
            for(int j=0;j<i;j++)///往前找寻美妙的回忆
            {
                if(a[j]<a[i])
                {
                    dp[i]=std::max(dp[i],dp[j]+1);
                }
            }
        }
        for(int i=0;i<n;i++)
        {
            if(i==0)
                printf("%d",dp[0]);
            else
                printf(" %d",dp[i]);
        }
        printf("
    ");
    }
    
    int main()
    {
        int t,n;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            for(int i=0;i<n;i++)
                scanf("%d",&a[i]);
            solve(n);
        }
    }

    优化为O(nlogn)  AC

    #include "cstdio"
    #define N 100005
    #include "algorithm"
    using namespace std;
    int n;
    int a[N];
    int dp[N];
    int ans[N];
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&a[0]);
            int top=1;///最长上升子序列长度
            dp[1]=a[0];///=最后一个元素
            ans[0]=top;///每个位置的 最长上升..长度
            
            for(int j=1;j<n;j++)///对每个元素
            {
                scanf("%d",&a[j]);
                if(a[j]>dp[top])///变长
                {
                    top++;
                    dp[top]=a[j];
                    ans[j]=top;
                }
                else
                {
                    int pos=lower_bound(dp,dp+top,a[j])-dp;///二分查找位置 替换元素
                    dp[pos]=a[j];
                    ans[j]=pos;
                }
            }
            for(int i=0;i<n;i++)
            {
                if(i==0)
                    printf("%d",ans[i]);
                else
                    printf(" %d",ans[i]);
            }
            printf("
    ");
        }
    }

     若只要最长...,只输出ans[n-1]

    可将上述解法当做一模板

    #include <iostream>  
    #include <stdio.h>  
    #include <algorithm>  
    #include <string.h>  
    using namespace std;  
    int dp[20];  
    const int inf=0x7fffffff;  
    int a[7]={2,1,3,4,8,5,9};  
    const int maxn=500005;  
    int main()  
    {  
        fill(dp,dp+7,inf);  
        for(int i=0;i<7;i++)  
        {  
            *lower_bound(dp,dp+7,a[i])=a[i];  
        }  
        int len=lower_bound(dp,dp+7,inf)-dp;  
        for(int i=0;i<len;i++)  
            cout<<dp[i]<<endl;  
        return 0;  
    }
    View Code
  • 相关阅读:
    codevs 1115 开心的金明
    POJ 1125 Stockbroker Grapevine
    POJ 2421 constructing roads
    codevs 1390 回文平方数 USACO
    codevs 1131 统计单词数 2011年NOIP全国联赛普及组
    codevs 1313 质因数分解
    洛谷 绕钉子的长绳子
    洛谷 P1276 校门外的树(增强版)
    codevs 2627 村村通
    codevs 1191 数轴染色
  • 原文地址:https://www.cnblogs.com/kimsimple/p/6661559.html
Copyright © 2011-2022 走看看