开始试着用深度搜索做,超时了(对于时间复杂度没有概念)
这道题用动态规划。如果用自顶向下的方法,我们不知道结尾的是哪个点,所以不方便用。
如果我们采用自下而上的方法,用eatNum[i][j]表示从起点到达i, j 位置老鼠所吃的奶酪数,问题是一个节点可由几中不同的路径不同时得到,所以也会发现也会有重复的路要走。
书上的动态规划方法其实挺妙。用起点作为终点的样子,自顶向下,把结果集结到起点。看来我的思维是太局限了。
向各个方向探索用一个for循环实现也是非常值得借鉴的。
#include <iostream>
#include <cstring>
using namespace std;
#define size 110
int a[size][size], n, k, eatNum[size][size];
int memSearch(int r, int c){
int r1, c1; //新的位置
int Max = 0;
int i, temp;
if(eatNum[r][c] != -1) //中间结果
return eatNum[r][c];
//每次让FatMouse走一步,直到走k步
for(i = 1; i <= k; i++){
//上
r1 = r - i;
if(r1 >= 1 && r1 <= n && a[r1][c] > a[r][c]){
temp = memSearch(r1, c);
if(temp > Max)
Max = temp;
}
//下
r1 = r + i;
if(r1 >= 1 && r1 <= n && a[r1][c] > a[r][c]){
temp = memSearch(r1, c);
if(temp > Max)
Max = temp;
}
//左
c1 = c - i;
if(c1 >= 1 && c1 <= n && a[r][c1] > a[r][c]){
temp = memSearch(r, c1);
if(temp > Max)
Max = temp;
}
//右
c1 = c + i;
if(c1 >= 1 && c1 <= n && a[r][c1] > a[r][c]){
temp = memSearch(r, c1);
if(temp > Max)
Max = temp;
}
}
eatNum[r][c] = Max + a[r][c];
return eatNum[r][c];
}
int main(){
//freopen("in.txt", "r", stdin);
int i, j;
while(cin>>n>>k){
if(n == -1 && k == -1)
break;
memset(eatNum, -1, sizeof(eatNum)); //存储中间结果
for(i = 1; i <= n; i++){
for(j = 1; j <= n; j++)
cin>>a[i][j]; //接收数据
}
cout<<memSearch(1, 1)<<endl;
}
return 0;
}