有乙個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
注意,這道題不能採用bfs,雖然求的是最優解,可是若採用bfs不一定能保證得到的是最小min_cost,本質是因為問題求得的解並不是隨步數的增大而一定增大的,它還考慮了節點的value,state。很明顯這不是線性遞增的,因此不能用bfs。這道題本質上還是考察圖的遍歷,這次用的dfs。
在dfs開始的時候需要剪枝(去掉一些情況,減小時間複雜度),因為這裡要求的是最小的代價,當在找路的時候發現當前的代價已經大於min_cost的時候,就不需要考慮從當前點往下的路徑,因為應經不可能是最優的路。
因為每次執行乙個動作,都需要用到前乙個的狀態和目前的代價和,所以在dfs的引數中要有這兩個變數。
為了避免在找路的過程中出現死迴圈,需要設定visit變數,防止在找其中某一條路徑的時候往回走,也就是說在每次執行到某個點的時候,將visit的值設為1;為了防止訪問過的點,在尋找第二條新路徑的時候還可以被訪問,我們需要將visit的值在每次dfs之後,重新初始化為0,這點我開始的時候沒有考慮到。
但是不知道為什麼顯示wrong answer。
#include
#include
#include
using
namespace
std;
intmap[6][6];
int start_x,start_y,end_x,end_y;
bool mark[6][6];
int move[4][2] = ,,,}; //對應向右,左
int min_cost=10000;
void dfs(int x,int y,int cost,int state)
int i;
for(i=0;i<4;i++)}}
}int main()
cin>>start_x>>start_y>>end_x>>end_y;
dfs(start_x,start_y,0,1);
printf("%d\n",min_cost);
} return
0;
}
OJ 1091 棋盤遊戲
include using namespace std const int n 6 const int d 4 const int inf 100000000 int direct 4 2 右,左,上,下 int g n n int visit n n int mincost 0 bool chec...
DFS和BFS 解棋盤遊戲(九度OJ 1091)
dfs利用遞迴,不必使用多餘的資料結構,實現簡單。但要注意剪枝。bfs借助佇列,往往在求最優解時使用。總是能找到最優解,某些情況下也要剪枝。這兩種方法根據具體問題來使用。以此題為例,dfs和bfs都可求解。由於是求最優解,用bfs更為直接。由於此題的不確定性,必須要考慮所有可能情況,結合剪枝。題目1...
九度 1091 棋盤遊戲
題目描述 有乙個6 6的棋盤,每個棋盤上都有乙個數值,現在又乙個起始位置和終止位置,請找出乙個從起始位置到終止位置代價最小的路徑 1 只能沿上下左右四個方向移動 2 總代價是沒走一步的代價之和 3 每步 從a,b到c,d 的代價是c,d上的值與其在a,b上的狀態的乘積 4 初始狀態為1 每走一步,狀...