记忆化搜索+简单dp
hdu-1078 FatMouse and Cheese题目链接:点击打开链接
题意:老鼠每次只能走K步停下来,所以多加一个for循环即可。停下的位置只能比上次停下的位置价值大
其实就是滑雪问题的加强版。用一个数组保存记忆。。。。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define max(a,b) a<b?b:a
int n,k;
int map[111][111],sum[111][111];//sum[][]保存记忆。。。
int dir[4][2]={0,-1,0,1,-1,0,1,0};
int dfs(int x,int y)
{
int m,ans=0;
if(sum[x][y])
return sum[x][y];
for(int i=0;i<4;i++)
{
for(int j=1;j<=k;j++) //遍历各个距离1~k
{
int s,t;
s=x+dir[i][0]*j; //取点
t=y+dir[i][1]*j;
if(s>=0&&s<n&&t>=0&&t<n)
{
if(map[s][t]>map[x][y]) //下一个点必须比当前点数值大
{
m=dfs(s,t);//记录下一个点的最大值
ans=max(ans,m);
}
}
}
}
sum[x][y]=ans+map[x][y];
return sum[x][y];//返回当前点的最大值
}
int main()
{
while(scanf("%d%d",&n,&k),n!=-1&&k!=-1)
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&map[i][j]);
memset(sum,0,sizeof(sum));
int ans=dfs(0,0);
printf("%d\n",ans);
}
return 0;
}
下面是滑雪代码:大家可以参考对比一下,,,也方便自己复习总结。。。
#include <stdio.h>
#include <string.h>
int dir[4][2]={1,0,-1,0,0,1,0,-1};//方向
int dp[101][101],map[101][101];//dp[x][y]保存记忆。。。
int m,n;
int max(int x,int y)
{
return x>y?x:y;
}
bool limit(int x,int y)//是否出界
{
if(x<0||y<0||x==m||y==n)
return false;
return true;
}
int dfs(int x,int y)
{
if(dp[x][y]!=0) return dp[x][y];
for(int i=0;i<4;i++)
{
int x_i=x+dir[i][0];
int y_i=y+dir[i][1];
if(limit(x_i,y_i)&&map[x][y]>map[x_i][y_i]&&dp[x][y]<dfs(x_i,y_i)+1)
dp[x][y]=dp[x_i][y_i]+1;
}
return dp[x][y];
}
int main()
{
while(scanf("%d %d",&m,&n)!=EOF)
{
memset(map,0,sizeof(map));
memset(dp,0,sizeof(dp));
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
scanf("%d",&map[i][j]);
int num=0;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
num=max(num,dfs(i,j));
}
printf("%d\n",num+1);
}
return 0;
}