Problem Description
有个小老鼠在校园里收藏了一些它最爱吃的奶酪。
校园可以看成一个长度为n的正方形网格,每个网格可以标记为(p,q),其中,0 <= p , q < n. 每个网格都有一个洞,里面储存了k(0<=k<=100)块奶酪。
现在,小老鼠准备享用这些美味啦。
开始的时候,他在(0,0)这个位置,每到一个地方,它都会吃光这个地方的奶酪,然后沿着水平或者垂直的方向到达另外一个地方。麻烦的是,有个很凶的猫总是在它的洞口附近,所以他每次最多移动K个位置,否则就会被这只猫吃掉。更糟糕的是,每在一个地方吃过奶酪,小老鼠都会变胖,所以,为了获得足够下一次逃跑的能量,它每次只能去比当前位置的奶酪更多的格子。
现在已知n和k,以及在每个网格的洞中小老鼠储存的奶酪的数量,请计算小老鼠在无法移动之前,一共最多能吃到多少块奶酪。
Input
题目包含多组测试数据。
每组测试数据组成如下:
首先一行包含2个不超过100的正整数n和k;
接下来n行,每行包含n个数:
第一行n个数分别表示 (0,0) (0,1) … (0,n-1)这些位置储存的奶酪数量;
第二行n个数分别表示(1,0), (1,1), … (1,n-1)这些位置储存的奶酪数量;
以此类推。
输入数据以两个-1结束。
Output
请输出小老鼠最多 能够吃到的奶酪数量,每组数据输出一行。
Sample input
3 1
1 2 5
10 11 6
12 12 7
-1 -1
Sample output
37
记忆化dfs
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int dp[N][N],g[N][N];
bool vis[N][N];//没有必要使用vis数组因为是要求是严格单调递增的
int n,k;
int dfs(int x,int y)
{
if(~dp[x][y]) return dp[x][y];
int ans=0;
for(int i=0;i<4;++i)
for(int j=1;j<=k;++j)
{
int xx=x+dir[i][0]*j;
int yy=y+dir[i][1]*j;
if(xx>=0&&xx<n&&yy>=0&&yy<n&&g[xx][yy]>g[x][y])
{
ans=max(ans,dfs(xx,yy));
}
}
return dp[x][y]=ans+g[x][y];
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
while(cin>>n>>k,~n)
{
memset(dp,-1,sizeof dp);
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
cin>>g[i][j];
vis[0][0]=1;
cout<<dfs(0,0)<<'\n';
}
return 0;
}
posted on
浙公网安备 33010602011771号