题目大意:
在一个n*n的网格中,每个格子中有一个权值,要求每次只能沿横竖方向走且当前格的权值要比上一格大,另外每次横竖移动的最大距离不能超过k
思路:
dp[i][j]表示到(i,j)的最大权值和
dp[i][j] = max{dp[i + m][j + m] | abs(m) <= k && g[i + m][j + m] > g[i][j] } + g[i][j]
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=110;
int d[maxn][maxn],g[maxn][maxn];
int n,m;
int dp(int x,int y)
{
if(d[x][y]>0) return d[x][y];
int val = g[x][y];
int temp = val;
for(int i=x-m;i<=x+m&&i<n;i+=1)
{
if(i<0) continue;
if(g[x][y]<g[i][y]) temp=max(temp,val+dp(i,y));
}
for(int i=y-m;i<=y+m&&i<n;i+=1)
{
if(i<0) continue;
if(g[x][y]<g[x][i]) temp=max(temp,val+dp(x,i));
}
return d[x][y]=temp;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n==-1) break;
memset(g,0,sizeof(g));
memset(d,0,sizeof(d));
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
scanf("%d",&g[i][j]);
}
}
int ans=dp(0,0);
printf("%d\n",ans);
}
}