题目:
Description
1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。
Input
Output
Sample Input
5 5 1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9
Sample Output
25思路:
一开始我是以为,山峰肯定只有一个峰,那这样的话,找到最高的那个点,在它周围慢慢找高度减小的点就好了。后来发现我太naive了,下面就是其中一组测试数据。
12 13
1 1 30 4 800 6 7 8 99 10 1223 1
20 30 30 4 16 15 14 13 12 11 1
21 22 99 444444 88 9926 27 9928 9929 3000 456 1
40 39 1 90 36 35 34 33 3992 30001 789 1
41 42 4000 44 88 46 47 48 49 50 897 1
1 59 1 57 56 85 54 53 52 51 908 1
61 77 56 64 444 66 67 68 69 70 1234 1
80 79 78 77 76 75 74 73 72 71 12345 1
81 82 2 2 4 86 5 88 8 90 3456 1
100 99 98 97 96 95 94 93 92 91 567 1
890 654 623 154 683 15414 86549 633 123 456 123456 1
9517 45632 643164 3478643 43 16 431 64453132 689431 746546 15643 1
64543 13146543 13474 314789 4352154 65431 631 654324 65132 89547 34567312 1 1
答案是27
所以不能想得太简单。正确的思路应该是这样的:题意为,给出一个二维数组,让你求出最长递减序列长度,可以四个方向行走,起点任意。要对于每个点,都算出到达1的最长路径。
如果单纯的递归,会超时,时间限制只有1000ms,所以加点小技巧,每次第一次访问一个点,就记录它到达1的最长路径,当下次访问时,就直接返回记录的值。即用一个数组dis[101][101]存储每个节点的最长路径,先初始化为0,每当访问一个节点时,就判断dis值是否大于0,大于0则此点的值就是dis的值,直接返回。
代码:
#include
using namespace std;
int map[101][101]={0};//存原始数据
int r,c;//行数,列数
int dis[101][101]={0};//存储节点的最长路劲值
int f(int form,int to){
if(dis[form][to]>0)return dis[form][to];//如果已经记录了值,直接返回
int zuo=0,you=0,shang=0,xia=0;
if(form+1<=r){//处理上路
if(map[form+1][to]
//循环出四个方面的最长序列然后len[i][j]=max(len[上],下,左,右)+1;
#include
#define N 101
using namespace std;
int map[N][N],len[N][N];
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int r,c;
int dp(int i,int j){
if(len[i][j]!=0)return len[i][j];
int maxx=0,s;
for(int t=0;t<4;t++){
int temx=i+dir[t][0],temy=j+dir[t][1];
if(temx>=0&&temx=0&&temymaxx)maxx=s;
}
}
len[i][j]=maxx+1;
return maxx+1;
}
int main(){
cin>>r>>c;
int mx=-1;
memset(len,0,sizeof(len));
for(int i=0;i>map[i][j];
}
}
for(int i=0;imx){
mx=len[i][j];
}
}
}
cout<