The Legend of Zelda

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lv414333532/article/details/82667020

The Legend of Zelda

Time Limit: 1000 ms Memory Limit: 65536 KiB

Submit Statistic Discuss

Problem Description

Fish 真的非常喜欢打游戏,最近又沉迷于塞尔达传说,现在 Fish 刚刚打通了雷咒盖侬解放了神兽瓦·纳波利斯,准备前往死亡火山去挑战火咒盖侬。

现在 Fish 刚刚回到了格鲁德小镇上,我们知道死亡火山在地图的右上角,但是格鲁德小镇在地图的左下角,之间有非常远的距离,地图上会有不少的驿站用来休息,但是 Fish 不想为了路过驿站而走远路,现在 Fish 想安排一个旅行的路线,使得经过的驿站尽可能的多,请你编写一个程序帮助他!

抽象一下题意,在一个二维坐标轴上,现在给出起点终点和 N 个点 Pi 的坐标,选择尽可能多的点组成一个序列,使得序列中点的 x 和 y 坐标都是递增的。

Input

多组输入(不超过10组)

 对于每组数据:

  • 第一行包括四个数 x1,y1,x2,y2,分别代表起点的横纵坐标,终点的横纵坐标(x1 < x2, y1 < y2)
  • 第二行输入一个整数 N,代表有 N 个点
  • 接下来 N 行,每行输入一个点的坐标 xi,yi 

0 <= N <= 1000

保证所有点的坐标大小在 32 位整数之内

Output

每组数据输出一行整数,为找出的最长序列长度(包含起点和终点)

Sample Input

1 1 9 9
5
0 8
3 2
3 3
4 3
7 1

Sample Output

4

Hint

第一组样例找出的最长序列只有 {(1, 1), (3, 2), (4, 3), (9, 9)} 长度为 4

Source

【2017级《程序设计基础(B)II》期末上机考试】Fish_li

分析:能否想到是排序后是个最长上升子序列的长度问题;

需要注意以下几点:1.考虑对数对排序。

                                    2.排序后能否搜索,DFS,搜索的复杂度为多少?太大了,会TLE的,下边有常试;

                                    3.想到最长上升子序列问题,考虑如何动态规划;状态转移方程;

                                    dp[i]=max(dp][i],dp[j]+1);(j<i&&dp[i]>dp[j]);

                                   因为dp[i]仅是当前最优值,不是到该值的所有的最优值,故需要比较所有当前的最优值;

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

struct node
{
    int x,y;
    bool operator <(const node &A)const
    {
        return (x<A.x)||(x==A.x&&y<A.y); //从小到大排序;
    }
}que[1010];
int dp[1010];
node S,E;
int top;
bool judge(node A) //去杂,去除不符合条件的点;
{
    return (A.x>S.x&&A.y>S.y&&A.x<E.x&&A.y<E.y);
}
int main()
{
    int n;
    while(~scanf("%d%d%d%d",&S.x,&S.y,&E.x,&E.y))
    {
        scanf("%d",&n);
        top=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&que[i].x,&que[i].y);
            if(judge(que[i]))
            {
                que[top++]=que[i];
            }
        }
    sort(que,que+top);
    for(int i=0;i<top;i++)
    {
        dp[i]=1;
    }
    int Max=0;
    for(int i=0;i<top;i++)
    {
        for(int j=0;j<i;j++)
        {
            if(que[i].x>que[j].x&&que[i].y>que[j].y)
            {
                dp[i]=max(dp[i],dp[j]+1);
            }
        }
        Max=max(Max,dp[i]);
    }
    printf("%d\n",Max+2);
    }
    return 0;
}

TLE版本

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
struct node
{
    int x,y;
    bool operator< (const node &a)const
    {
        return (x<a.x)||(x==a.x&&y<a.y);
    }
    bool operator== (const node &a)const
    {
        return a.x==x&&a.y==y;
    }

}A[1010];

int n,k;
int ans;
node point1,point2;

void DFS(int s,int num)
{
    for(int i=s+1;i<n;i++)
    {
        if(A[i]==point2)
        {
            ans=max(ans,num);
            return;
        }
        else if(A[i].x>A[s].x&&A[i].y>A[s].y)
        {
            DFS(i,num+1);
            //return;
        }
    }
    return;
}
int main()
{
    while(~scanf("%d%d%d%d",&point1.x,&point1.y,&point2.x,&point2.y))
    {
        scanf("%d",&n);
        ans=-1;
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&A[i].x,&A[i].y);
        }
        A[n]=point1;
        A[n+1]=point2;
        n+=2;
        sort(A,A+n);
        for(int i=0;i<n;i++)
        {
            if(A[i]==point1)
            {
                k=i;break;
            }
        }
      DFS(k,2);
      printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/lv414333532/article/details/82667020
今日推荐