题意:n*m的网格,有些格子里可能有宝藏,若站在(x,y),每次只能向(x+1,y)或者(x,y+1)方向走,问最少要走几趟能将网格中的宝物收集完。
分析: 按题目的意思就是只能向右和向下走。如果将宝物的坐标按x轴来从小到大排(x轴相同的按y轴从小到大),那么就可以只考虑y坐标了
,假设有两个位置i,j,i.x<=j.x,当i.y<=j.y时,才有可能收集完i后收集j,所以按x轴排序完后,问题就转化为用最少几个不降子序列可将y轴坐标序列全部涵盖。那就是最长(严格)递减子序列的长度了。
 #include <iostream>
#include <iostream>
 #include <stdio.h>
#include <stdio.h>
 #include <memory.h>
#include <memory.h>
 #include <algorithm>
#include <algorithm>
 using namespace std;
using namespace std;

 struct node
struct node


 {
{
 int x,y;
    int x,y;
 }a[100010];
}a[100010];

 int dp[100010],num[100010],b[100010],n,m,p;
int dp[100010],num[100010],b[100010],n,m,p;

 int cmp(node p,node q)
int cmp(node p,node q)


 {
{
 if(p.x==q.x) return p.y<q.y;
    if(p.x==q.x) return p.y<q.y;
 return p.x<q.x;
    return p.x<q.x;
 }
}

 void solve()    // 求最长递减子序列
void solve()    // 求最长递减子序列


 {
{
 int i,tem,l,r,mid,ans,top;
    int i,tem,l,r,mid,ans,top;
 b[1]=num[1]; top=1; dp[1]=1;
    b[1]=num[1]; top=1; dp[1]=1;
 ans=0;
    ans=0;
 for(i=2;i<=p;i++)
    for(i=2;i<=p;i++)

 
     {
{
 if(num[i]<b[top])
        if(num[i]<b[top])

 
         {
{
 b[++top]=num[i];
            b[++top]=num[i];
 dp[i]=top;
            dp[i]=top;
 }
        }
 else
        else

 
         {
{
 l=1; r=top;
            l=1; r=top;
 while(l<=r)
            while(l<=r)

 
             {
{
 mid=(l+r)>>1;
                mid=(l+r)>>1;
 if(b[mid]<=num[i])
                if(b[mid]<=num[i])

 
                 {
{
 tem=mid;
                    tem=mid;
 r=mid-1;
                    r=mid-1;
 }
                }
 else l=mid+1;
                else l=mid+1;
 }
            }
 b[tem]=num[i];
            b[tem]=num[i];
 dp[i]=tem;
            dp[i]=tem;
 }
        }
 if(dp[i]>ans) ans=dp[i];
        if(dp[i]>ans) ans=dp[i];
 }
    }
 printf("%d\n",ans);
    printf("%d\n",ans);
 }
}

 int main()
int main()


 {
{
 int i;
    int i;
 while(scanf("%d%d%d",&m,&n,&p)!=EOF)
    while(scanf("%d%d%d",&m,&n,&p)!=EOF)

 
     {
{
 for(i=1;i<=p;i++)
        for(i=1;i<=p;i++)
 scanf("%d%d",&a[i].x,&a[i].y);
            scanf("%d%d",&a[i].x,&a[i].y);
 sort(a+1,a+1+p,cmp);
        sort(a+1,a+1+p,cmp);
 for(i=1;i<=p;i++)
        for(i=1;i<=p;i++)
 num[i]=a[i].y;
            num[i]=a[i].y;
 solve();
        solve();
 }
    }
 return 0;
    return 0;
 }
}