【UOJ451】楼兰宝藏

【题目描述】:
在魔法世界的历史上,楼兰是个充满了神秘色彩的名字。那座昔日绿草遍地人往如织的繁荣古城──楼兰,在公元4 世纪以后,却突然神秘地消失了,留下的只是 “城郭巍然,人物断绝”的不毛之地和难解之谜。

不过著名冒险家席慕蓉在一次探险中发现,原来被沙丘掩埋的楼兰古国地下,埋藏着不计其数的宝藏。

简单说来,就是在一张 N×M的地图(N行M列),地图上画有P个宝藏(1<=N,M<=10^9,P<=100000),每次当探险者坐标为 (x行,y列)时,他可以向 (x+1,y)或 (x,y+1)移动一格,问最少要多少次才能拣起所有的宝藏(每次走到最后一步时,会自动传送回左上角位置)。

【输入描述】:
第一行有三个整数,分别为N,M,P。余下P行分别为每个宝藏的X、Y坐标。

【输出描述】:
一个整数,即次数。

【样例输入】:
7 7 7
1 2
1 4
2 4
2 6
4 4
4 7
6 6
【样例输出】:
2
【时间限制、数据范围及描述】:
时间:1s 空间:256M

30%的数据:1<=N,M<=10,P<=10

60%的数据:1<=N,M<=10^9,P<=10000

100%的数据:1<=N,M<=10^9,P<=100000


题解:前几天写的程序咳咳咳,迟了几天。其实这道题木像导弹拦截升级版,求需要多少个不降子序列才能将所有点包括在内。虽然有大数据,不过暴力也过了哈哈。先结构体排序,然后就是不断找这个点(枚举)可不可以和前面的宝藏连成通路,如果可以则更新此路最新节点。如果不可以则“开辟新航路”。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
const int N=100005;
int n,m,t,ans=1;
struct node{
    int x;
    int y;
}a[N];
node way[N];
int dd=1;
bool cmp(node p,node q){
    if(p.x==q.x) return p.y<q.y;
    else return p.x<q.x;
}
bool pd(int p,int q){
    for(int i=1;i<=dd;i++){
        if(p>=way[i].x  && q>=way[i].y){
            way[i].x=p; way[i].y=q; return 1;
        }
    }
    return 0;
}
int main(){
    scanf("%d %d %d",&n,&m,&t);
    if(n==1 || m==1) {
        printf("1");
        return 0;
    }
    for(int i=1;i<=t;i++)
        scanf("%d %d",&a[i].x,&a[i].y);
    sort(a+1,a+t+1,cmp);
    for(int i=1;i<=t;i++){
        bool gf=pd(a[i].x,a[i].y);
        if(gf==0){
            way[++dd].x=a[i].x;
            way[dd].y=a[i].y;
        }
    }
    cout<<dd;
    return 0;
}
原文地址:https://www.cnblogs.com/wuhu-JJJ/p/11133597.html