天天看點

滑雪問題(貪心)

滑雪問題(貪心)

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
/*POJ1088題滑雪問題
将滑雪點從高到低排序,向四個方向延伸,找出延伸距離最長的*/
struct node  //滑雪點 
{
  int x;  //行 
  int y;  //列 
  int h;  //高度 
};
bool cmp(node a,node b)  //排序機制,從高到低排 
{
  return a.h>b.h;
}
int main()
{
  int t,n,m,maxLen,index,xx,yy;
  int len[105][105];   //長度數組 
  int height[105][105];  //高度數組 
  node a[105*105];  //滑雪點數組 
  cin>>t;   //輸入例子 
  while(t--)
  {
    cin>>n>>m;   //輸入行和列 
    index=0; //滑雪點數組的下标 
    maxLen=0;  //最長延伸距離 
    memset(len,0,sizeof(len));
    memset(height,0,sizeof(height));
    for(int i=1;i<=n;i++)
       for(int j=1;j<=m;j++)
       {
           cin>>height[i][j];
           a[index].x=i;
           a[index].y=j;
           a[index].h=height[i][j];
           len[i][j]=1;   //初始化每個點的延伸長度都為1,即它自己 
           index++;
       }
    sort(a,a+index,cmp);  //從高到低排序 
      for(int i=0;i<index;i++)  //從高到低周遊每一個滑雪點 
      {
        xx=a[i].x;   yy=a[i].y;
        //為什麼要小于号,是要找出最長下降子序列,就是找出延伸長度最長的下降點 
        if(a[i].h<height[xx-1][yy])  
           len[xx][yy]=max(len[xx][yy],len[xx-1][yy]+1);
      if(a[i].h<height[xx+1][yy])  
           len[xx][yy]=max(len[xx][yy],len[xx+1][yy]+1);
      if(a[i].h<height[xx][yy-1])  
           len[xx][yy]=max(len[xx][yy],len[xx][yy-1]+1);
      if(a[i].h<height[xx][yy+1])  
           len[xx][yy]=max(len[xx][yy],len[xx][yy+1]+1); 
        if(maxLen<len[xx][yy])  maxLen=len[xx][yy];  //取出最長的延伸距離 
    }
    cout<<maxLen<<endl;
  }
  return 0;
}