滑雪问题(贪心)
滑雪问题的是POJ1088,方法有贪心、二维dp求最长下降子序列、记忆化搜索
我开始疑惑疑惑一点,在贪心策略为什么是从高到低还要小于号
延伸是向四个方向延伸
后来一想这是求下降的最长延伸长度
贪心代码如下:
#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;
}