题意:在二维数组中找最长的下降序列,可以向上、下、左、右,四个方向走

思路:len[i][j] = max{上,下,左,右},还需要考虑height[i][j]与上下左右的关系。

  这个方程的子问题填表方式有两种:一是,迭代方式,用一个结构体记录height[i][j]、i、j,然后对高度排序,然后从小到大填表,这样就能保证填len[i][j]时,其上下左右如果不比   height[i][j]大则一定填过了;二,用备忘录方式,直接递归处理。

 我用的第二种,因为当时没想起来怎么迭代处理,就用备忘录了,后来仔细想了想递归的时候的调用关系,想出了第一种方法.

代码:

 

#include<cstdio>
using namespace std;

int height[100][100];
int len[100][100]; //初始化为-1
int r, c;

int get_len(int i, int j){
if(len[i][j] >= 0)
return len[i][j];

int tmp;
int max = 0;
//
if((i-1) >= 0 && height[i-1][j] < height[i][j]){
tmp
= get_len(i-1, j) + 1;
if(tmp > max)
max
= tmp;
}
//
if((i+1) < r && height[i+1][j] < height[i][j]){
tmp
= get_len(i+1, j) + 1;
if(tmp > max)
max
= tmp;
}
//
if((j-1) >= 0 && height[i][j-1] < height[i][j]){
tmp
= get_len(i, j-1) + 1;
if(tmp > max)
max
= tmp;
}
//
if((j+1) < c && height[i][j+1] < height[i][j]){
tmp
= get_len(i, j+1) + 1;
if(tmp > max)
max
= tmp;
}
return max;
}

int main(){
// freopen("in", "r", stdin);

scanf(
"%d %d", &r, &c);
for(int i=0; i<r; ++i)
for(int j=0; j<c; ++j){
scanf(
"%d", &height[i][j]);
len[i][j]
= -1;
}
int max_len = 0;
for(int i=0; i<r; ++i)
for(int j=0; j<c; ++j){
len[i][j]
= get_len(i, j);
if(len[i][j] > max_len)
max_len
= len[i][j];
}
printf(
"%d", max_len + 1);

return 0;
}

 

 

我又把第一种迭代法的程序写出来了:

 

#include<cstdio>
#include
<algorithm>
using namespace std;

#define MAX 100
struct index {
int x;
int y;
};

int height[MAX][MAX];
index order[MAX
* MAX]; //对高度的排序
int len[MAX][MAX];
int r, c;

//用于排序的比较对象
struct cmp {
bool operator()(index a, index b) {
return (height[a.x][a.y] < height[b.x][b.y]);
}
};

//按顺序填表
void fill() {
int i, j;
int max, tmp;
for (int k = 0; k < r * c; ++k) {
i
= order[k].x;
j
= order[k].y;

max
= 0;
//
if ((i - 1) >= 0 && height[i - 1][j] < height[i][j]) {
tmp
= len[i - 1][j] + 1;
if (tmp > max)
max
= tmp;
}
//
if ((i + 1) < r && height[i + 1][j] < height[i][j]) {
tmp
= len[i + 1][j] + 1;
if (tmp > max)
max
= tmp;
}
//
if ((j - 1) >= 0 && height[i][j - 1] < height[i][j]) {
tmp
= len[i][j - 1] + 1;
if (tmp > max)
max
= tmp;
}
//
if ((j + 1) < c && height[i][j + 1] < height[i][j]) {
tmp
= len[i][j + 1] + 1;
if (tmp > max)
max
= tmp;
}

len[i][j]
= max;
}
}

int main() {
// freopen("in", "r", stdin);

scanf(
"%d %d", &r, &c);
for (int i = 0; i < r; ++i)
for (int j = 0; j < c; ++j) {
scanf(
"%d", &height[i][j]);
int k = i * c + j;
order[k].x
= i;
order[k].y
= j;
}
sort(order, order
+ r * c, cmp());

fill();

int max_len = 0;
for (int i = 0; i < r; ++i)
for (int j = 0; j < c; ++j)
if (len[i][j] > max_len) {
max_len
= len[i][j];
}
printf(
"%d", max_len + 1);

return 0;
}

 

 

 

posted on 2010-07-08 23:21  yongmou-  阅读(229)  评论(0编辑  收藏  举报