题目描述
有一个6*6的棋盘,每个棋盘上都有一个数值,现在又一个起始位置和终止位置,请找出一个从起始位置到终止位置代价最小的路径: 1、只能沿上下左右四个方向移动 2、总代价是没走一步的代价之和 3、每步(从a,b到c,d)的代价是c,d上的值与其在a,b上的状态的乘积 4、初始状态为1 每走一步,状态按如下公式变化:(走这步的代价%4)+1。
输入描述:
每组数据一开始为6*6的矩阵,矩阵的值为大于等于1小于等于10的值,然后四个整数表示起始坐标和终止坐标。
输出描述:
输出最小代价。
示例1
输入
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
0 0 5 5
输出
23
题目解析:还是一个回溯问题,从当前位置出发(每次走过的点需要记录已经走过了,不能再走),然后经过上下左右,(例如,先从上然后下一步可能走上,左,右),记录每次不同方案走到目标点的代价,比较记录出最小代价。
代码:
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<vector>
#include<map>
#include<iomanip>
using namespace std;
int ans = 0x3f3f3f3f; //代价定义为最大数
int matrix[6][6];
int x_1 , y_1 , x_2 , y_2;
int a[] = {-1,1,0,0}; //移动,只有四个移动,一行向左,向右,向上,向下
int b[] = {0,0,1,-1};
int visit[6][6]; //记录此时是否使用了该点
//深度遍历,从该点出发进行上下左右移动,直到到达最后目标点
void dfs(int x,int y,int now,int status){ //xy当前位置,now代价,status状态
if(x == x_2 && y == y_2){ //如果当前点 == 结束点,输出最小代价
ans = min(ans , now); //ans记录不同走法到达目标点后的最小代价
}
visit[x][y] = 1; //标记该点已经走过了
for(int i = 0; i < 4; i++){
int xx = x + a[i], yy = y + b[i]; //移动位置
if(xx < 0 || xx > 5 || yy < 0 || yy > 5 || visit[xx][yy] == 1){ //超出棋盘范围,或者已经选过了
continue; //跳出本次循环,此路不通。
}
int cost = matrix[xx][yy] * status;
int new_status = (cost % 4) + 1;
dfs(xx , yy , now + cost , new_status); //继续走,直到到达目的地
}
visit[x][y] = 0;
}
int main()
{
for(int i = 0 ; i < 6; i++){
for(int j = 0 ; j < 6; j++){
cin >> matrix[i][j];
}
}
memset(visit,0,sizeof(visit)); //初始化选中状态
cin >> x_1 >> y_1 >> x_2 >> y_2 ;
dfs(x_1 , y_1 , 0 , 1); //从目标地点出发,代价,状态
cout << ans << endl; // 输出最小代价
return 0;
}