-
题目描述:
-
有一个6*6的棋盘,每个棋盘上都有一个数值,现在又一个起始位置和终止位置,请找出一个从起始位置到终止位置代价最小的路径:
1、只能沿上下左右四个方向移动
2、总代价是没走一步的代价之和
3、每步(从a,b到c,d)的代价是c,d上的值与其在a,b上的状态的乘积
4、初始状态为1每走一步,状态按如下公式变化:(走这步的代价%4)+1。
-
输入:
-
第一行有一个正整数n,表示有n组数据。
每组数据一开始为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
-
-
这道题莫名其妙,WA了好多次,把起点的mark矩阵不初始化就A了,难道还能再回到起点吗?
-
DFS+剪枝
-
-
#include <stdio.h> const int INF = 0x7fffffff; int weight[6][6]; bool mark[6][6]; int sx, sy, ex, ey; int go[][2] = {1,0,-1,0,0,1,0,-1}; int res; void DFS(int x, int y, int cost, int sta) { if(x == ex && y == ey) { if(res > cost) res = cost; return; } if(res < cost) return; //剪枝 for(int i = 0; i < 4; i++) { int nx = x + go[i][0]; int ny = y + go[i][1]; if(nx < 0 || nx > 5 || ny < 0 || ny > 5) continue; if(mark[nx][ny] == true) continue; mark[nx][ny] = true; int ncost = sta * weight[nx][ny]; DFS(nx,ny,cost+ncost,ncost%4+1); mark[nx][ny] = false; } } int main() { //freopen("Test.txt","r",stdin); int n; scanf("%d",&n); while(n--) { int i, j; for(i = 0; i < 6; i++) { for(j = 0; j < 6; j++) { scanf("%d",&weight[i][j]); mark[i][j] = false; } } scanf("%d%d%d%d",&sx,&sy,&ex,&ey); //mark[sx][sy] = true; res = INF; DFS(sx,sy,0,1); printf("%d\n",res); } return 0; }