时间限制: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;
}