商人過河問題(n個)-Matlab
n個商人過河問題
Description
商人過河問題:n名商人各帶一名隨從過河,一隻小船隻能容納z個人,隨從們約定,只要在河的任何一岸,一旦隨從人數多於商人人數就殺人越貨,但是商人們知道了他們的約定,並且如何過河的大權掌握在商人們手中,商人們該採取怎樣的策略才能安全過河並且渡河次數最少呢??
Explaination
- 先從一般的例子開始討論,通過3名商人各帶一名隨從過河,一隻小船隻能容納3個人,從此岸的角度確定安全矩陣。再遞推,確定n名商人各帶一名隨從過河,一隻小船隻能容納z個人的安全狀態矩陣(0、1)的規律
- 然後分類討論,設立判定條件,來討論什麼情況下不存在安全過河狀態以及對安全矩陣的遍歷,通過設定單元陣列來儲存渡河所有過程,以便於後續查詢和判斷
- 最後通過判斷此岸商人、僕人是否都已經到達彼岸來選擇出最少渡河次數,並輸出一組結果;如果不存在安全到達的情況則輸出No answer!
Example
- 當n=3,z=3時,渡河的最少次數、此岸的商人數和僕人數變化如下:
-
k = 5 W = 3 3 3 1 3 2 0 2 0 3 0 0
- 當n=5,z=3時,渡河的最少次數、此岸的商人數和僕人數變化如下:
k = 11 W = 5 5 5 3 5 4 5 1 5 2 2 2 3 3 0 3 0 4 0 2 0 3 0 0
Code
:對於不同情況的m、z只需要修改程式碼中的m、z即可。
% Matlab clear; home; m=3; %商人、僕人數 z=3; %船上可載人數 m=m+1; %矩陣中不存在0位置 A=zeros(m); %列表示商人,行表示僕人 for i=0:m-1 %尋找安全狀態,1為安全,0為不安全 for j=0:m-1 if (i==j)||(i==m-1)||(i==0) A(i+1,j+1)=1; end end end s={}; %用來存放路徑 p=1; %用來表示放在每一行的第幾列 R=[]; %特殊情況 s{1,1}=[m,m,1]; %[a,b,c]a表示此岸商人數,b表示此岸僕人數,c表示由上面情況c推的 for t=1:100 %迴圈上界適當 flag=0; %用來判斷是否重複 trump=0; %用來判斷是否已經存在可安全渡河的情況 k=t; %k表示渡河次數 if z>=2*(m-1) %當船載人數大於或等於總人數 k=1 R=[m-1,m-1;0,0] break; end for a=1:sum(~cellfun(@isempty, s(k,:))) %表示有幾種情況(相對於同一個k來說) if a==1 %第一種情況,從第一個列開始存 p=1; end n1=s{k,a}(1,1); %賦值,商人數 n2=s{k,a}(1,2); %賦值,僕人數 for i=0:z %渡河 for j=0:z if (i+j>=1 && i+j<=z) && (n1+i*(-1)^k<=m && n1+i*(-1)^k>=1) && (n2+j*(-1)^k<=m && n2+j*(-1)^k>=1) && (A(n1+i*(-1)^k,n2+j*(-1)^k)==1) %條件判斷 if k>=2 %判斷是否重複 for e=1:sum(~cellfun(@isempty, s(k-1,:))) if (s{k-1,e}(1,1)==n1+i*(-1)^k) && (s{k-1,e}(1,2)==n2+j*(-1)^k) flag=1; %如果發現重複,則flag==1 break; end end end if flag==0 %不重複存入 s{k+1,p}=[n1+i*(-1)^k,n2+j*(-1)^k,a]; p=p+1; end flag=0; %每一次判斷之後flag都要歸0 end end end end k=k+1; %一次考慮完後k+1 s{k+1,1}=[]; %往下建立空cell if sum(~cellfun(@isempty, s(k,:)))==0 %判斷是否有新的情況生成,0表示s{k,:}全部為空 'No answer!' break; end for win=1:sum(~cellfun(@isempty, s(k,:))) %判斷是否已有完成任務的情況 if s{k,win}(1,1)==1 && s{k,win}(1,2)==1 trump=1; break; end end if trump==1 k=k-1 break; end end if trump==1 %輸出一組結果 W=[]; qq=win; for oo=1:k+1 W(oo,1)=s{k+2-oo,qq}(1,1)-1; W(oo,2)=s{k+2-oo,qq}(1,2)-1; qq=s{k+2-oo,qq}(1,3); end W=flipud(W) end
<第一次寫部落格>ヽ(○^㉨^)ノ♪
相關推薦
商人過河問題(n個)-Matlab
n個商人過河問題 Description 商人過河問題:n名商人各帶一名隨從過河,一隻小船隻能容納z個人,隨從們約定,只要在河的任何一岸,一旦隨從人數多於商人人數就殺人越貨,但是商人們知道了他們的約定,並且如何過河的大權掌握在商人們手中,商人們該採取怎樣的
商人過河問題的Python實現
# -*- coding: cp936 -*- #定義允許存在的狀態集合 def allowexistset(): merchants=int(raw_input("請輸入商人數: ")) slivers=int(raw_input("請輸入隨從數: ")) allowset
商人過河問題(DFS)
問題描述: 3個商人帶著3個僕人過河,過河的工具只有一艘小船,只能同時載兩個人過河,包括划船的人。在河的任何一邊,只要僕人的數量超過商人的數量,僕人就會聯合起來將商人殺死並搶奪其財物,問商人應如何設計過河順序才能讓所有人都安全地過到河的另一邊。 詳細過程參見《數學模型》第四
商人過河 決策
這是上數模老師講的一道題,解法有圖解法和遞迴窮舉的方式,這裡我採用後者。 詳細說明可以參考:http://www.docin.com/p-970116457.html 程式碼: #include<cstdio> #include<cstring> #
晚上,有n個人過河,分別需要n1、n2、n3、nn分鐘。只有一把手電筒,過河的必要條件是有手電筒。最多可以兩個人同時過河,但必須以兩人中較慢的那個人的速度過去。問:所有人都過河,至少需幾分鐘。
package Arrays; import java.util.Arrays; import java.util.Scanner; public class ToArray { private
爸爸 媽媽 獵人和狗 有兩男孩 兩個女孩 。他們要過河,但獵人不在的時候,狗咬任何人,當爸爸不在的時候,媽媽打小男孩,媽媽不在的時候,爸爸打小女孩,他們怎麼過去
爸爸 媽媽 獵人和狗 有兩男孩 兩個女孩 。他們要過河,但獵人不在的時候,狗咬任何人,當爸爸不在的時候,媽媽打小男孩,媽媽不在的時候,爸爸打小女孩,他們怎麼過去 有一天看到的一個網上題目,一時興起便寫了一下,o(^▽^)o #include<stdio.h>
Linux awk統計日誌中出現過的IP(或出現次數最多的N個IP)
awk是一個強大的文字分析工具,相對於grep的查詢,sed的編輯,awk在其對資料分析並生成報告時,顯得尤為強大。簡單來說awk就是把檔案逐行的讀入,以空格為預設分隔符將每行切片,切開的部分再進行各種分析處理。 awk的用法 awk 'BEGIN{ commands }
Java從檔案中跳過n個位元組讀取資料
下面例項是跳過前10個位元組,從第11個位元組開始讀取File file = new File("tcp.txt"); FileInputStream stream = new java.io.FileInputStream(file);
[數學模型]商人怎樣安全過河
問題描述 三名商人各帶一個隨從乘船渡河,一隻小船隻能容納兩人,由於他們自己划行,隨從密約,在和的任一岸,一旦隨從的人數比商人多,就殺人越貨,但是如何安排乘船的大權安排在商人們的手中,商人們怎樣才能安全渡河? 模型假設 我們需要對問題做一些假設:
過河問題 貪心
開始 難度 pac map sca 的人 names 最優 sort 過河問題 時間限制:1000 ms | 內存限制:65535 KB 難度:5 描述 在漆黑的夜裏,N位旅行者來到了一座狹窄而且沒有護欄的橋邊。如果不借助手電筒的話,大家是無論如何也不敢過橋去的
luogu P1809 過河問題_NOI導刊2011提高(01)
-m iostream style 人才 三次 nbsp code mat 問題 題目描述 有一個大晴天,Oliver與同學們一共N人出遊,他們走到一條河的東岸邊,想要過河到西岸。而東岸邊有一條小船。 船太小了,一次只能乘坐兩人。每個人都有一個渡河時間T,船劃到對
【DP】青蛙過河
現在 div col 接受 printf mic ive 開始 可能 Description 在河上有一座獨木橋,一只青蛙想沿著獨木橋從河的一側跳到另一側。在橋上有一些石子,青蛙很討厭踩在這些石子上。由於橋的長度和青蛙一次跳過的距離都是正整數,我們可以把獨木橋上青蛙
n個括號對的所有可能情況
括號 main color 思路 出棧 gin col r+ div 所有可能情況的數量為卡特蘭數。故求所有可能的出棧情況與此類似。 思路: 若左括號沒全插入,則插入左括號; 若已插入左括號數比已插入右括號數多,則插入右括號; 1 #include<st
這些Linux數據恢復工具,你用過哪幾個
linux數據恢復不論你運用的是臺式電腦仍是筆記本,需求重視的要點之一都是怎麽保護好你的名貴數據。由於總會有各種突發狀況使你的系統潰散,然後你要做的就是恢復數據。不論你怎麽想,要是我失去了一切的數據卻無法恢復的話,我會分分鐘肢解了這臺破電腦。不過幸虧的是,如今商場上有不少的數據恢復工具,能協助咱們從體系的硬盤
luogu P1002 過河卒
for clas tro ret iostream article 表示 格式 strong 題目描述 棋盤上A點有一個過河卒,需要走到目標B點。卒行走的規則:可以向下、或者向右。同時在棋盤上C點有一個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因
歐幾裏得算法以及擴展歐幾裏得算法(過河noip2005提高組第二題)
font 以及 family nbsp 最大公約數 這樣的 noi 其他 sun 歐幾裏得算法:也被稱作輾轉相除法 gcd(a,b)=gcd(b,a%b); 終止條件a=gcd b=0; (gcd為a,b的最大公約數) 擴展歐幾裏得算法: a 和 b 的最大公約數是 g
codevs 1245 最小的N個和
pan width 長度 spa dev char getc 初始 turn 題目描述 Description 有兩個長度為 N 的序列 A 和 B,在 A 和 B 中各任取一個數可以得到 N^2 個和,求這N^2 個和中最小的 N個。 輸入描述 Input
《劍指offer》 面試題43 n個骰子的點數 (java)
r+ nal ret 次循環 分而治之 源碼 ava 面試 ble 引言:寫這篇文章的初衷只是想做個筆記,因為這道題代碼量有點大,有點抽象,而書上並沒有詳細的註釋。為了加深印象和便於下次復習,做個記錄。 原題:把n個骰子扔到地上,所有骰子朝上一面的點數之後為s. 輸入n,打
過河卒
cnblogs https ring string end lan tar stream alt 鏈接 分析:當前點的情況僅由其左邊和上邊的點決定,然後馬會走過的點標記一下即可 1 #include "iostream" 2 #include "cstdio" 3
(hdu step 7.1.6)最大三角形(凸包的應用——在n個點中找到3個點,它們所形成的三角形面積最大)
三角形 struct names com 都在 acm sni 都是 tran 題目:最大三角形Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S