题意:(n, m)的迷宫,每个点都有一个值,从(1, 1)走到(n, m) 有三种走法:移动到(x+1,y),(x,y+1)或者(x,y*k),其中k>1,问走到(n,m)的最大价值。
思路:和HDU1078很像,记忆化搜索就行。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 25;
const int maxm = 1e4+5;
const int INF = 0x3f3f3f3f;
int dp[maxn][maxm], a[maxn][maxm], k, ans;
bool vis[maxn][maxm];
int row, col;
int dfs(int x, int y)
{
if(vis[x][y]) return dp[x][y];
// getchar();
// cout << x << ' ' << y << endl;
int next[2][2] = {1, 0, 0, 1}, sum = -INF;
for(int i = 0; i < 2; i++)
{
int tx = x+next[i][0];
int ty = y+next[i][1];
if(tx > 0 && ty > 0 && tx <= row && ty <= col)
sum = max(sum, dfs(tx, ty));
}
for(int i = 1; y && (y+i*y <= col); i++)
{
int tx = x;
int ty = y+i*y;
sum = max(sum, dfs(tx, ty));
}
vis[x][y] = 1;
return dp[x][y] = sum+a[x][y];
}
int main(void)
{
int t;
cin >> t;
while(t--)
{
scanf("%d%d", &row, &col);
memset(dp, 0, sizeof(dp));
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= row; i++)
for(int j = 1; j <= col; j++)
scanf("%d", &a[i][j]);
vis[row][col] = 1;
dp[row][col] = a[row][col];
cout << dfs(1, 1) << endl;
}
return 0;
}