棋盘游戏

时间限制:1秒 
空间限制:65536K 
热度指数:426
 算法知识视频讲解

题目描述

    有一个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

深搜+剪枝,本来想用记忆化搜索的,用dp[x][y][t]记录,但是不对,因为每次搜索的时候不能重复经过一个点,而这是无法记录的。

// pat.cpp : 定义控制台应用程序的

//#include "stdafx.h"
#include"stdio.h"
#include<iostream>
#include<string>
#include<vector>
#include<math.h>
using namespace std;
typedef long long ll;
const int maxn=100;
int s[6][6];
int a,b,c,d;
int hashtable[6][6]={0};
int dir[4][2]={0,1,0,-1,1,0,-1,0};
int dp[6][6][6]={0};
int res=0x7fffffff;
void dfs(int x,int y,int t,int sum){
	if(sum>res)return ;//剪枝
	
	if(x==c&&y==d) {res=min(res,sum);return;}
	int x1;
	int y1;
	
	for(int i=0;i<4;i++){
	x1=x+dir[i][0];
	y1=y+dir[i][1];
        if(!hashtable[x1][y1]&&x1<6&&x1>=0&&y1<6&&y1>=0){
	int price=s[x1][y1]*t;
	hashtable[x1][y1]=1;
	dfs(x1,y1,price%4+1,sum+price);
	
	
	hashtable[x1][y1]=0;
		}}
	
	




}




int main(){

	//freopen("c://jin.txt","r",stdin);
	while(cin>>s[0][0]){
	for(int i=0;i<6;i++)
		for(int j=0;j<6;j++){
			if(i==0&&j==0)continue;
			cin>>s[i][j];	}
	cin>>a>>b>>c>>d;
	int t=1;
	dfs(a,b,1,0);
	cout<<res<<endl;

	
	
	
	
	
	
	}


	//freopen("CON","r",stdin);
	//system("pause");

	return 0;
}

    原文作者:骑士周游问题
    原文地址: https://blog.csdn.net/qq_30339595/article/details/79401712
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞