代码改变世界

FatMouse and Cheese(记忆化搜索)

2019-07-30 19:27  木木王韦  阅读(134)  评论(0)    收藏  举报

FatMouse and Cheese

有一种游戏是的玩法是这样的:
有一个n*n的格子,每个格子有一个数字。
遵循以下规则:

  1. 玩家每次可以由所在格子向上下左右四个方向进行直线移动,每次移动的距离不得超过m
  2. 玩家一开始在第一行第一列,并且已经获得该格子的分值
  3. 玩家获得每一次移动到的格子的分值
  4. 玩家下一次移动到达的格子的分值要比当前玩家所在的格子的分值要大。
  5. 游戏所有数字加起来也不大,保证所有数字的和不会超过int型整数的范围
  6. 玩家仅能在n*n的格子内移动,超出格子边界属于非法操作
  7. 当玩家不能再次移动时,游戏结束
    现在问你,玩家所能获得的最大得分是多少?
    Input
    有多组测试数据
    每组测试样例第一行是两个整数n,m (1≤n≤100)(1≤m≤100),当n和m都是-1时为程序结束标志,直接退出即可
    之后n行,每行n个数字,描述n*n的格子里的数字
    Output
    对于每组测试数据输出一行,这一行仅有一个整数,代表玩家所能获得的最高得分
    Sample Input
    3 1
    1 2 5
    10 11 6
    12 12 7
    -1 -1
    Sample Output
    37

和“滑雪”那道题的不同之处在于这道题不止遍历四周,在m个距离内都可以,这道题求得是最长递减的路径相加的值

ac代码:

#include<iostream>
#include<string.h>

using namespace std;

int d[4][2]={0,1,0,-1,1,0,-1,0};
int n,m,ma[101][101];
int dp[101][101];

int dfs(int x,int y){//cout<<"c"<<x<<"   "<<y<<endl;
	if(dp[x][y]>0) return dp[x][y];
	
	else{
	int maxn=0;
	int sum;
	int xx,yy;
	for(int i=0;i<4;i++){
		for(int j=1;j<=m;j++){
			//cout<<"i:"<<i<<endl;
			//cout<<"**"<<d[i][0]<<"  "<<d[i][1]<<endl;
			xx=x+j*(d[i][0]);
			yy=y+j*(d[i][1]);
			//cout<<"xx:"<<xx<<"  "<<yy<<endl; 
			if(xx>=0&&xx<n&&yy>=0&&yy<n&&ma[xx][yy]>ma[x][y]){
				//cout<<"78676";
				sum=dfs(xx,yy);
				maxn=max(maxn,sum);
			}
		} 
	} 
	 dp[x][y]=ma[x][y]+maxn;
	 //cout<<"x:"<<x<<"  Y;"<<y<<"  "<<dp[x][y]<<endl;
	 return dp[x][y];
	}
	
}



int main(){
	//cout<<d[0][0]<<"  "<<d[0][1]<<endl;
	while(cin>>n>>m&&(n!=-1||m!=-1)){
		memset(dp,0,sizeof(dp));
		memset(ma,0,sizeof(m));
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				cin>>ma[i][j];
			}
		}
		dfs(0,0);
		/*for(int i=0;i<n;i++){
        	for(int j=0;j<n;j++){
        		cout<<dp[i][j]<<" ";
			}
			printf("\n");
		}*/
		cout<<dp[0][0]<<endl;
	}
	
	
	return 0;
}