关闭

HDU 1025 Constructing Roads In JGShining's Kingdom 最长子序列的nlogn算法

195人阅读 评论(0) 收藏 举报
分类:

    题意是说在路两旁分别有富裕的城市和穷困的城市,他们之间打算连接起来,而每个城市间只会有1条路(比如1连到2就不会再出现1连到3,表示一开始忽略了这点......然后考虑了半天这种情况怎么处理才好......),而且这些路之间不能交叉,给出现在想连在一起的城市的计划方案,问最多能连几条路出来。

    看上去很复杂,但其实上,只要按一边城市的顺序排好,再求出另一边的最长子序列就可以了,因为一边排好之后,只要另一边的数字比前面大,那么就一定不会出现交叉,于是,用最长子序列来做......

    下面代码,TLE了......

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct road
{
    int st;
    int en;
};

int maxlen[500005];
road a[500005];

int cmp(road x,road y)
{
    if(x.st!=y.st)
        return x.st<y.st;
    return x.en<y.en;
}

int max(int x,int y)
{
    return x>y?x:y;
}

int main()
{
    int n;
    int i,j,k=0;
    int t;
    int ans;
    while(scanf("%d",&n)!=EOF)
    {
        k++;
        for(i=0;i<n;i++)
        {
            scanf("%d%d",&a[i].st,&a[i].en);
            maxlen[i]=1;
        }
        sort(a,a+n,cmp);
        for(i=1;i<n;i++)
        {
            for(j=0;j<i;j++)
            {
                if(a[i].en>a[j].en)
                {
                    maxlen[i]=max(maxlen[i],maxlen[j]+1);
                }
            }
        }
        ans=*max_element(maxlen,maxlen+n);
        cout<<"Case "<<k<<":"<<endl;
        if(ans==1)
            cout<<"My king, at most 1 road can be built."<<endl<<endl;
        else
            cout<<"My king, at most "<<ans<<" roads can be built."<<endl<<endl;
    }
    return 0;
}

    好吧,结果就是,超时了= =然而之前有最长子序列的题我都是怎样写的啊......好吧,百度了下发现,原来还有更快的方法,这种方法是O(n^2),而还有一种O(nlogn)的求最长子序列算法,果然,参考着网上的改正过来后就AC了......

    简单来说这种方法就是记录下来递增子序列的最小末尾,然后不断更新,用下一个数与这些最小末尾再进行比较与插入,而在比较的时候可以采用二分查找的方式,这样复杂度就只需nlogn就可以得出结果了。

    这里贴一个学习时看到的博客地址,里面对这个算法的过程说的很详细,我就不具体的再说了= =:http://blog.csdn.net/shuangde800/article/details/7474903

    然后下面是AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct road
{
    int st;
    int en;
};

road a[500005];
int b[500005],c[500005];

int cmp(road x,road y)
{
    if(x.st!=y.st)
        return x.st<y.st;
    return x.en<y.en;
}

int max(int x,int y)
{
    return x>y?x:y;
}

int fin(int *t,int len,int n)
{
    int left=0,right=len,mid=(left+right)/2;
    while(left<=right)
    {
        if(n>t[mid])
            left=mid+1;
        else if(n<t[mid])
            right=mid-1;
        else
            return mid;
        mid=(left+right)/2;
    }
    return left;
}

int main()
{
    int n;
    int i,j,k=0;
    int t;
    int len;
    while(scanf("%d",&n)!=EOF)
    {
        k++;
        for(i=0;i<n;i++)
        {
            scanf("%d%d",&a[i].st,&a[i].en);
        }
        sort(a,a+n,cmp);
        b[0]=1;
        c[0]=-1;
        c[1]=a[0].en;
        len=1;
        for(i=1;i<n;i++)
        {
            j=fin(c,len,a[i].en);
            c[j]=a[i].en;
            if(j>len)
                len=j;
        }
        cout<<"Case "<<k<<":"<<endl;
        if(len==1)
            cout<<"My king, at most 1 road can be built."<<endl<<endl;
        else
            cout<<"My king, at most "<<len<<" roads can be built."<<endl<<endl;
    }
    return 0;
}


1
0
查看评论

HDU1025:Constructing Roads In JGShining's Kingdom(LIS)

Problem Description JGShining's kingdom consists of 2n(n is no more than 500,000) small cities which are located in two parallel lines. Half o...
  • libin56842
  • libin56842
  • 2013-07-30 17:18
  • 1672

杭电OJ——1025 Constructing Roads In JGShining's Kingdom(比较有趣的一道题目,思路详解)

Constructing Roads In JGShining's Kingdom Problem Description JGShining's kingdom consists of 2n(n is no more than 500,000) small cities wh...
  • lishuhuakai
  • lishuhuakai
  • 2012-11-10 01:48
  • 3291

hdu 1025 Constructing Roads In JGShining's Kingdom(LIS)题意较难转换成LIS

1、http://acm.hdu.edu.cn/showproblem.php?pid=1025 题目好难懂,懂了之后也没想到这是一个LIS的题目,注意输出的细节,wrong了n遍 输出,注意一条多条的不同输出,样例之间打印空行 2、题目大意 有2n个城市,其中有n个富有的城市,n个贫穷的城...
  • sdjzping
  • sdjzping
  • 2013-04-05 21:17
  • 2551

HDU - 1025 Constructing Roads In JGShining's Kingdom

题意:有贫困和富有的地方,每个地方只能连接一个地方,不能有交叉,给你n条线,求最多的连接条数 思路:LIS的应用,尽量的往前连 #include #include #include #include using namespace std; const int INF = 0x3f3f3f3...
  • u011345136
  • u011345136
  • 2014-03-15 19:20
  • 679

Hdu 1025 - Constructing Roads In JGShining's Kingdom

用二分查找,不知为何一直RE,数组明明开的足够了。 RE代码: #include int num[500001]; int ans[500001]; int main() { int n, k=1, len, p, r, i; int low, mid, high; whi...
  • Chuck_0430
  • Chuck_0430
  • 2013-04-19 19:18
  • 783

hdu 1025 Constructing Roads In JGShining's Kingdom

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1025 转化为求最大上升子序列,我自己学这个算法的时候的理解:http://blog.csdn.net/fallenfall/article/details/11748941 写的时候注意细节,哪个roa...
  • fallenfall
  • fallenfall
  • 2013-09-16 22:29
  • 585

hdu 1025 Constructing Roads In JGShining's Kingdom

Problem Description JGShining's kingdom consists of 2n(n is no more than 500,000) small cities which are located in two parallel lines. Half o...
  • fanesemyk
  • fanesemyk
  • 2016-07-30 19:56
  • 131

hdu 1025 Constructing Roads In JGShining's Kingdom

二维DP会超时。。。。 点击打开链接 假设存在一个序列d[1..9] = 2 1 5 3 6 4 8 9 7,可以看出来它的LIS长度为5。 下面一步一步试着找出它。 我们定义一个序列B,然后令 i = 1 to 9 逐个考察这个序列。 此外,我们用一个变量Len来记录现在最长算到...
  • yyf573462811
  • yyf573462811
  • 2012-07-27 15:41
  • 741

HDU 1025 Constructing Roads In JGShining's Kingdom

LIS #include #include #include #include #include using namespace std; #define sf scanf #define pf printf #define rep(i,n) for(int (i)=0;(i)&...
  • utoppia
  • utoppia
  • 2013-11-10 15:55
  • 396

HDU 1025:Constructing Roads In JGShining's Kingdom

Description JGShining's kingdom consists of 2n(n is no more than 500,000) small cities which are located in two parallel lines.  Half of th...
  • KingJordon
  • KingJordon
  • 2016-08-11 19:46
  • 83
    个人资料
    • 访问:36344次
    • 积分:1764
    • 等级:
    • 排名:千里之外
    • 原创:130篇
    • 转载:5篇
    • 译文:0篇
    • 评论:10条
    文章分类
    QQ二维码(添加请写明备注)
    最新评论