现在的位置: 首页 > 综合 > 正文

最长上升子序列练习 – from lanshui_Yang

2019年01月07日 ⁄ 综合 ⁄ 共 2065字 ⁄ 字号 评论关闭

POJ  3903 Stock Exchange :

       此题也是简单的最长上升子序列问题,但由于数列长度n较大(n <= 100000),所以普通的O(n^2)是会超时的,所以要用O(nlogn)算法。加输入输出优化后直接进status前三名,哈哈

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std ;
const int MAXN = 1e5 + 5 ;
int s[MAXN] ;
int dp[MAXN] ;
int n ;
int stap[MAXN] ;
int top ;
inline void RD(int &a)  
{
    a = 0 ;
    char t ;
    do
    {
        t = getchar() ;
    }while ( t < '0' || t > '9') ;
    a = t - '0' ;
    while ((t = getchar()) >= '0' && t <= '9')
    {
        a = a * 10 + t - '0' ;
    }
}
inline void OT(int a)
{
    if(a >= 10)
    {
        OT(a / 10) ;
    }
    putchar(a % 10 + '0') ;
}
void init()
{
    int i , j ;
    for(i = 1 ; i <= n ; i ++)
    {
        //scanf("%d" , &s[i]) ;
        RD(s[i]) ;
    }
}
void solve()  // O(n^2) 算法
{
    int i , j ;
    dp[1] = 1 ;
    for(i = 2 ; i <= n ; i ++)
    {
        dp[i] = 1 ;
        for(j = 1 ; j < i ; j ++)
        {
            if(s[i] > s[j] && dp[i] < dp[j] + 1)
            {
                dp[i] = dp[j] + 1 ;
            }
        }
    }
    int MAX = -1 ;
    for(i = 1 ; i <= n ; i ++)
    {
        if(MAX < dp[i])
        MAX = dp[i] ;
    }
    printf("%d\n" , MAX) ;
}

void solve2()  // O(n log n) 算法
{
    top = 0 ;
    stap[++ top] = s[1] ;
    int i ;
    for(i = 2 ; i <= n ; i ++)
    {
        if(s[i] > stap[top])
        {
            stap[++ top] = s[i] ;
        }
        else if(s[i] < stap[top])
        {
            int left , right , mid ;
            left = 1 ;
            right = top ;
            while (left < right)
            {
                mid = (left + right) / 2 ;
                if(stap[mid] < s[i])
                {
                    left = mid + 1 ;
                }
                else if(stap[mid] == s[i])
                {
                    break ;
                }
                else
                {
                    right = mid ;  // 注意不是 mid - 1  !!
                }
            }
            mid = (left + right) / 2 ;
            stap[mid] = s[i] ;
        }
    }
    OT(top) ;
    puts("") ;
}
int main()
{
    while (scanf("%d" , &n) != EOF)
    {
        init() ;
        //solve() ;
        solve2() ;
    }
    return 0 ;
}

POJ 1631 Bridging signals:

方法同上,只不过输入发生了点变化。

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std ;
const int MAXN = 1e5 + 5 ;
int s[MAXN] ;
int dp[MAXN] ;
int n ;
int stap[MAXN] ;
int top ;
inline void RD(int &a)
{
    a = 0 ;
    char t ;
    do
    {
        t = getchar() ;
    }while ( t < '0' || t > '9') ;
    a = t - '0' ;
    while ((t = getchar()) >= '0' && t <= '9')
    {
        a = a * 10 + t - '0' ;
    }
}
inline void OT(int a)
{
    if(a >= 10)
    {
        OT(a / 10) ;
    }
    putchar(a % 10 + '0') ;
}
void init()
{
    RD(n) ;
    int i , j ;
    for(i = 1 ; i <= n ; i ++)
    {
        RD(s[i]) ;
    }
}
void solve2()  // O(n log n) 算法
{
    top = 0 ;
    stap[++ top] = s[1] ;
    int i ;
    for(i = 2 ; i <= n ; i ++)
    {
        if(s[i] > stap[top])
        {
            stap[++ top] = s[i] ;
        }
        else if(s[i] < stap[top])
        {
            int left , right , mid ;
            left = 1 ;
            right = top ;
            while (left < right)
            {
                mid = (left + right) / 2 ;
                if(stap[mid] < s[i])
                {
                    left = mid + 1 ;
                }
                else if(stap[mid] == s[i])
                {
                    break ;
                }
                else
                {
                    right = mid ;  // 注意不是 mid - 1  !!
                }
            }
            mid = (left + right) / 2 ;
            stap[mid] = s[i] ;
        }
    }
    OT(top) ;
    puts("") ;
}
int main()
{
    int T ;
    scanf("%d" , &T) ;
    while (T --)
    {
        init() ;
        solve2() ;
    }
    return 0 ;
}

 

抱歉!评论已关闭.