HDU 1025 Constructing Roads In JGShining's Kingdom(LIS的O(nlogn)算法)

题目地址:点击打开链接

题意:一条河的2边住着穷人和富人,一个富人只打算和一个特定穷人之间建一座桥,问最多能建多少个桥

思路:O(n^n)的会超时,主要思想看后面大神解析

错误代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>

using namespace std;

const int maxn = 500010;

struct node
{
    int poor,rich;
}a[maxn];

int dp[maxn];

bool cmp(node x,node y)
{
    return x.poor < y.poor;
}

int main()
{
    int n,i,j,cas = 1;
    while(scanf("%d",&n) != EOF)
    {
        for(i=0; i<n; i++)
        {
            scanf("%d%d",&a[i].poor,&a[i].rich);
            dp[i] = 1;
        }
        sort(a,a+n,cmp);
        for(i=1; i<n; i++)
        {
            int max1 = 0,p = 0;
            for(j=0; j<i; j++)
            {
                if(a[i].rich > a[j].rich && dp[j] > max1)//这句话每次都会执行,导致dp[i]是错的
                {
                    max1 = dp[j];
                    p = j;
                }
            }
            if(p != 0)//i==1的时候p正好为0
            {
                dp[i] = max1 + 1;
            }
        }
        int max2 = 0;
        for(i=0; i<n; i++)
        {
            if(dp[i] > max2)
                max2 = dp[i];
        }
        printf("Case %d:\n",cas++);
        if(max2 == 1)
        {
            printf("My king, at most 1 road can be built.\n\n");
        }
        else
        {
            printf("My king, at most %d roads can be built.\n\n",max2);
        }
    }
    return 0;
}

逻辑比较混乱,写错了,重写了一个

超时代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>

using namespace std;

const int maxn = 500010;

struct node
{
    int poor,rich;
}a[maxn];

int dp[maxn];

bool cmp(node x,node y)
{
    return x.poor < y.poor;
}

int main()
{
    int n,i,j,cas = 1;
    while(scanf("%d",&n) != EOF)
    {
        memset(dp,0,sizeof(dp));
        for(i=0; i<n; i++)
        {
            scanf("%d%d",&a[i].poor,&a[i].rich);
        }
        sort(a,a+n,cmp);
        dp[0] = 1;
        for(i=1; i<n; i++)
        {
            int max1 = 0;
            for(j=0; j<i; j++)
            {
                if(a[i].rich > a[j].rich && dp[j] > max1)
                {
                    max1 = dp[j];
                }
            }
            dp[i] = max1 + 1;//没有符合条件的就为1,有符合条件的就加1
        }
        int max2 = 0;
        for(i=0; i<n; i++)
        {
            if(dp[i] > max2)
                max2 = dp[i];
        }
        printf("Case %d:\n",cas++);
        if(max2 == 1)
        {
            printf("My king, at most 1 road can be built.\n\n");
        }
        else
        {
            printf("My king, at most %d roads can be built.\n\n",max2);
        }
    }
    return 0;
}

思路正确,超时了

AC代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>

using namespace std;

const int maxn = 500010;
int a[maxn],stack1[maxn];

int main()
{
    int n,i;
    int poor,rich,cas = 1;
    while(scanf("%d",&n) != EOF)
    {
        for(i=0; i<n; i++)
        {
            scanf("%d%d",&poor,&rich);
            a[poor] = rich;
        }
        int top = 0;
        stack1[0] = 0;
        for(i=1; i<=n; i++)
        {
            if(a[i] > stack1[top])
            {
                stack1[++top] = a[i];
            }
            else
            {
                int low = 1,high = top,mid;
                while(low <= high)
                {
                    mid = (low + high) / 2;
                    if(a[i] > stack1[mid])
                    {
                        low = mid + 1;
                    }
                    else
                    {
                        high = mid - 1;
                    }
                }
                stack1[low] = a[i];//里面是low,high会导致错误,细节多注意
            }
        }
        printf("Case %d:\n",cas++);
        if(top == 1)
        {
            printf("My king, at most 1 road can be built.\n\n");
        }
        else
        {
            printf("My king, at most %d roads can be built.\n\n",top);
        }
    }
    return 0;
}

看了大神的思想A的,

大神地址1:点击打开链接

大神地址2:点击打开链接


你可能感兴趣的:(HDU 1025 Constructing Roads In JGShining's Kingdom(LIS的O(nlogn)算法))