hdu 1025 最长上升子序列+排序

本文介绍了一种基于二分查找的nlogn复杂度的最长上升子序列算法,并提供了完整的AC代码实现。该算法适用于解决特定条件下的路径构建问题。

因为题目给出不能交叉,一条边的两个点一个看做下标,一个看做值,那么就是 i>=j,then a[i] >=a[j] ,所以满足上升不降子序列,求建路条数最多,其实就是最长上升子序列

ac代码如下:

采用的是nlogn的二分法模板求取最长上升子序列模板及讲解链接


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define MAX 500007

using namespace std;

int n;

struct Road 
{
    int r,p;
    bool operator < ( const Road & a ) const 
    {
        if ( r == a.r ) return p < a.p;
        return r < a.r;
    }
}r[MAX];

int dp[MAX];
int d[MAX];

int get ( int n )
{
    int left = 0 , right = n-1 , mid;
    while ( left != right )
    {
        mid = (left + right+1) >> 1;
        if ( r[n].p >= d[mid] ) left = mid;
        else right = mid - 1; 
    }
    d[left+1] = min ( d[left+1] ,  r[n].p );
    return left + 1;
}


int main ( )
{
    int c = 1;
    while  (~scanf ( "%d" , &n ) )
    {
        for ( int i = 1 ; i <= n ; i++ ) scanf ( "%d%d" , &r[i].r , &r[i].p );
        sort ( r+1 , r+n+1 );
        memset ( d , 0x3f , sizeof ( d ) );
        d[0] = 0;
        int ans = 0;
        for ( int i = 1 ; i <= n ; i++ ) 
          ans = max ( ans ,  get( i ) );
        char s[50];
        if ( ans > 1 ) sscanf ( "roads" , "%s" , s );
        else sscanf ( "road" , "%s" , s );
        printf ( "Case %d:\n" , c++ );
        printf ( "My king, at most %d %s can be built.\n" , ans ,s );
        puts ( "" );
    }
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值