陆历川的宝藏

题目

  陆历川来到了一个神秘的城堡(n*m的矩阵),这个矩阵中有很多的钞票,他们分别位于不同的座标上,现在陆历川位于(1,1),但是他只能
向右或者向下走,最终走到(n,m)终点,但是陆历川无法一下把所有的钞票都拿走,现在他想知道他最少需要几次能把所有的钞票都拿走

输入
 N,M,P       N,M代表矩阵的大小, P代表有几个座标点有钞票
 接下来P行, 每行分别是钞票的座标(X,Y)

输出
 一个整数,即次数

样例输入

7 7 7
1 2
1 4
2 4
2 6
4 4
4 7
6 6

输出样例

2


解题思路


首先普及一下最长不上升子序列,例如下面的数字串
6 8 5 4 3 2 9
他的最长不上升子序列就是
6 5 4 3 2 长度为5

我们从最简单的图形考虑



如上图的两个点,我们可以发现无路如何都必须要两次才能完成,由此我们可以推断出,如果有K个点成为这样从右上向左下排开的链,那么取完这K个点至少需要K次。

这里的链不是笼统的一条斜线,是一种抽象的斜线,他是把所有的斜线合并的一条链,合并规则是先把X座标从小到大排序,然后以Y座标为关键字,求最长不上升子序列,这样的链不唯一,下图只画出了其中的一条。





这条链就是我们抽象的斜线,它的长度是4,其余的点只要不属于链,则肯定可以在某一取值时取走。

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
const int maxn = 1000 + 10 ;
struct point{
    int x ;
    int y ;
};
point ans[maxn] ;
int len[maxn] , p ;
bool cmp(point a , point b)
{
    if(a.x == b. x)
        return a.y < b. y ;
    return a.x < b. x ;
}
 int tofind(int x)
 {
     int l = 1 , r = p  , mid ;
     while(l <= r)
     {
         mid = (l + r) >> 1 ;
         if(len[mid] > x)
            l = mid + 1;
         else
            r = mid - 1 ;
     }
     return l ;
 }
int main()
{
    int n , m  ;
    while(scanf("%d %d" , &n , &m) != EOF)
    {
        memset(ans , 0 , sizeof(ans)) ;
        memset(len , 0 , sizeof(len)) ;
        scanf("%d" , &p) ;
        for(int i = 0 ; i < p ; i++){
            scanf("%d %d" , &ans[i].x , &ans[i].y) ;
        }
        sort(ans , ans + p , cmp) ;
      /*  for(int i = 0 ; i < p ; i++)
        {
            printf("ans[%d].y = %d\n" , i , ans[i].y) ;
        }*/
        int top = 0 ;
        len[++top] = ans[0].y ;
        for(int i = 1 ; i < p ; i++)
        {
            if(ans[i].y <= len[top])
            {
                len[++top] = ans[i]. y ;
            }
            else
            {
                int to = tofind(ans[i].y) ;
                len[to] = ans[i].y ;
            }
        }
      /* for(int i = 1 ; i <= top ; i++)
       {
           cout<<"len["<<i<<"] : " << len[i] << endl;
       }*/
        printf("%d\n" , top) ;
    }
    return 0 ;
}
/*
7 7 9
2 1
4 1
4 2
6 2
4 4
7 4
3 5
2 6
6 6
*/






发布了69 篇原创文章 · 获赞 58 · 访问量 5万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章