数据结构与算法 迷宫夺宝 C语言

迷宫夺宝

1.1 题目要求
一个N x N的矩阵代表了一个迷宫,迷宫中每个房间由以下三种数字的一种来表示:
    0 代表房间安全,是可以通过的。
    1 代表房间中有奖励物品,玩家可以拿到奖励并通过房间。
    -1 代表房间中有障碍,玩家不能通过房间。
    你的任务是在遵守下列规则的情况下,尽可能多的拿到奖励:
    玩家从起始位置 (0, 0) 出发,到达终点(N-1, N-1) ,只能向下或向右走,并且只能穿越有效的房间(即只可以穿过值为0或者1的房间);当到达 (N-1, N-1) 后,完成走动过程;当你经过一个房间且这个房间有奖励时,拿到奖励后这个房间会变成空的(值变为0);如果在(0, 0)和(N-1, N-1)之间不存在一条可经过的路径,则没有奖励能被拿到。

思路:DP + DFS 先找到能获得最大的奖励,再通过DFS从后往前找路径

#include<stdio.h>
#include<stdlib.h>

#define LEN 4
int matrix[LEN][LEN] = { 0, 1, 1, -1, 1, 0, -1, 0, 1, 1, 0, 1, -1, 0, 1, 0};
int DP[LEN + 1][LEN + 1] = {0}; 
int Route[LEN + 1][LEN + 1] = {0};

void PrintNums(int (*matrix)[LEN]){
	for(int i = 0; i < LEN; i++){
		for(int j = 0; j < LEN; j++){
			printf("%d ", matrix[i][j]);
		}
		printf("\n");
	}
}
void PrintDP(int (*matrix)[LEN + 1]){
	for(int i = 1; i < LEN + 1; i++){
		for(int j = 1; j < LEN + 1; j++){
			printf("%d ", matrix[i][j]);
		}
		printf("\n");
	}
}
int Max(int num1, int num2){
	return num1>=num2?num1:num2;
}
int FindMaxValue(int (*matrix)[LEN]){
	int MaxValue = 0;	
	for(int i = 1; i < LEN + 1; i++){
		for(int j = 1; j < LEN + 1; j++){
			if(matrix[i-1][j-1] != -1){
				MaxValue = Max(DP[i-1][j], DP[i][j-1]);
				DP[i][j] = MaxValue + matrix[i-1][j-1];
			}
		}
	}
	MaxValue = DP[LEN][LEN];
	return MaxValue;
}
void DFS(int i, int j){
	Route[i][j] = 1;//标记当前已经走过的路径
	printf("%d %d\n",i,j);
	if(i == 1 && j == 1){
		return;
	}
	if(j >= 2 && (DP[i][j] == DP[i][j-1] || DP[i][j] == DP[i][j-1] + 1)){
		DFS(i, j-1);//不加 >=2 会断错误 类似1 -1 1 -2
		return;//如果是寻找最大礼物的所有路径则无需加return 可见最后2
	}
	if(i >= 2 && (DP[i][j] == DP[i-1][j] || DP[i][j] == DP[i-1][j] + 1)){
		DFS(i-1, j);
		return;
	}

}
void FindRoute(int MaxValue){
	int i = LEN;
	int j = LEN;
	Route[i][j] = 1;
	Route[0][0] = 1;
	while(i != 0 && j != 0) {
    	if(DP[i][j-1] == MaxValue) {
        	Route[i-1][j] = 1;
        	i--;
      	}
		else if(DP[i][j-1] == MaxValue) {
        	Route[i][j-1] = 1;
        	j--;
        }
		else
		{
        	if(DP[i-1][j] == MaxValue - 1) {
            	Route[i-1][j] = 1;
            	i = i - 1;
           		MaxValue --;
        	}
			else {
            	Route[i][j-1] = 1;
           		j = j - 1;
            	MaxValue --;
            }
		}
    }
}
void main(){
	//int row = sizeof(matrix)/sizeof(matrix[0]);
	//int column = sizeof(matrix[0])/sizeof(matrix[0][0]);
	PrintNums(matrix);
	printf("获取最大礼物值:%d\n", FindMaxValue(matrix));
	//PrintDP(DP);
	//FindRoute(FindMaxValue(matrix));
	printf("DP动态规划后数组值\n");
	PrintDP(DP);
	DFS(LEN,LEN);
	printf("获取最大礼物值的路线\n");
	PrintDP(Route);
}

实验结果图:
结果示意图
没加return 递归过程会出现左和上两个分支去探测
结果示意图2

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值