小记:dfs超时,果断不能
思路:因为只能上下右三个方向,那么我从左到右依次处理每一列,然后处理下一列的时候再处理上一列的每一个值往右走能得到的值,用一个数组保存每个坐标格能得到的最大值,每处理完一列就得到了这一列每个点所能得到的最大值了,每一列根据从上一列某点往右然后上下更新当前列的所有点,时间复杂度O(n*n*m)
代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
using namespace std;
#define mst(a,b) memset(a,b,sizeof(a))
#define eps 10e-8
const int MAX_ = 110;
const int N = 100010;
const int INF = 0x7fffffff;
//int dir[3][2] = {{0,-1}, {1,0}, {0,1}};
//bool vis[MAX_][MAX_];
int mp[MAX_][MAX_];
int num[MAX_][MAX_];
int n, m, ans, cs;
void find(int x){
for(int i = 1; i <= n; ++i){
int tmp = num[i][x-1] + mp[i][x];
if(num[i][x] < tmp)num[i][x] = tmp;
for(int j = i+1; j <= n; ++j){
tmp += mp[j][x];
if(tmp > num[j][x])num[j][x] = tmp;
}
}
for(int i = n; i > 0; --i){
int tmp = num[i][x-1] + mp[i][x];
if(num[i][x] < tmp)num[i][x] = tmp;
for(int j = i-1; j > 0; --j){
tmp += mp[j][x];
if(tmp > num[j][x])num[j][x] = tmp;
}
}
}
int main(){
int T;
scanf("%d", &T);
for(int Ca = 1; Ca <= T; ++Ca){
scanf("%Id%d", &n, &m);
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= m; ++j){
scanf("%d", &mp[i][j]);
num[i][j] = -INF;
}
}
num[1][1] = mp[1][1];
for(int i = 2; i <= n; ++i){
num[i][1] = num[i-1][1] + mp[i][1];
}
for(int i = 2; i <= m; ++i){
find(i);
}
printf("Case #%d:\n%d\n",Ca, num[1][m]);
}
return 0;
}