有乙個人,乙隻羊,乙隻狼,一捆菜(狼可以吃羊,羊可以吃菜,只有人在的情況,才避免吃的情況),準備過河。有一條船隻能載兩樣東西過河(人也算是一樣東西,只有人才會往返坐船,其它不會),如何過才會全部安全過河(沒有吃的現象)?
分析:可用自動機方法來解決,乙個狀態可形式化表示為,即people、sheep、wolf、cabbage的四元組,<1,1,1,1>表示最終的狀態,<0,0,0,0>表示初始狀態;定義動作集<+1,1,0,0>,<+1,0,1,0>,<+1,0,0,1>,<-1,0,0,0>,<-1,-1,0,0>,<-1,0,-1,0>,<-1,0,0,-1>;定義合法狀態p=1||p=0&s=1&w=0&c=0||p=0&s=0&w=1;
這樣每乙個狀態在初始狀態s0<0,0,0,0>開始,都可以有4個分支,返回時也有4個分支,注意到每個分支不一定是有效的,所以這需要乙個可達性檢查的過程,主要的思路如下:
1.過河每次對應三個分支,若擴充套件的狀態中有任意乙個p,s,w,c大於1的,矛盾。對於返回後的狀態,若任意乙個p,s,w,c小於0的,也矛盾。
2.擴充套件後的狀態需滿足題目限制條件,即<0,1,1,0>,<0,1,1,1>,<0,1,0,1>以及<1,0,0,1>,<1,0,0,0>,<1,0,1,0>(對岸的情況不滿足)
遍歷過程中要確保nextstate是新狀態,這就需要對每個出現過的狀態進行記錄.
#include #include using namespace std;typedef struct state;
typedef struct pace ;
bool operator == (const state& sa, const state& sb)
state operator +(const state& t1,const state& action)
;typedef liststatelist;//f_state為狀態集合
statelist f_state;
statelist h_state;
state init_state=;
state end_state=;
state action_go[4]=,,,};
state action_back[4]=,,,};
state invalid_state[6]=,,,,,};
bool isvalid(state& t1)
return true;
};void getnextstate(int step)
{ state t1=f_state.back();
f_state.pop_back();
if(t1==end_state)
{cout<"<"<
人狼羊菜問題
引用自張銘老師的 資料結構與演算法三 公開課 人狼羊菜 乘船過河 人 狼 菜 羊 沒有過河位置0,已經過河位置1。0 0 0 0 初始值 1 0 0 1 1 1 1 1 全部過河 include include include bool famer int status bool wolf int ...
C 演算法 狼羊菜過河問題
namespace 狼羊菜過河問題 物件陣列 static string start new string 開始情況 static string end new string 結束情況 static int cnt objects.length 幾種物件 static int count 0 解決方...
練習程式 演算法系列14 狼 羊 菜和農夫過河問題
參考2 函式物件 關於仿函式 函式物件 ptr fun 參考3 bind2nd使用 include include include include using namespace std const int action count 8 一共有8種動作 int dfs deep 0 int resu...