uva10603 fill 倒水問題 解題報告:
題目大意:
設3個杯子的容量為abc,起初只有第三個杯子裝滿了c公升水。其它兩個杯子均為空。最少要倒多少公升水可以讓某乙個杯子裡有d公升水。如果無法做到d公升水。就讓某個杯子裡有d『公升水,其中d』分析:
這個樣子其實有一點點動態規劃的味道,其實不是。一看到這種求最小的倒水量。第一眼就應該想到用bfs。廣搜,可以完美的設計到這種狀態或者是抉擇問題。而這道題。3個杯子,假設在某一時刻第乙個杯子裡有v1公升水。第二個杯子有v2公升水,第三個杯子有v3公升水。而這個時候可以說是在某一時刻的狀態。「狀態」這個名詞很玄學,往往有很多的演算法和思想都會運用到狀態這個概念。而每個狀態之間都可以通過某種方式進行轉換,這道題就是通過倒水。
迴圈來兩,兩倒水,倒出後的結果放到乙個新的狀態,新的狀態進隊。(進隊之前要判重。)理論上就有 (a+1)(b+1)(c+1)=8120601種狀態,這個狀態有點多。記憶體有點多。但是呢,這種判斷是不精確的。因為,水就那麼多。當a,b的量確定之後,c的量就確定了,所以這麼大的狀態就一下縮小到201^2=40401;這就小多了。
而在一般的bfs中目標狀態最先搜尋到的一定是步驟最小的乙個目標狀態,而這道題求的不是最小步驟的目標狀態而是倒水量最小的目標狀態,所以,這裡的佇列應該用到優先佇列,優先佇列裡的判斷條件就是根據每種狀態的倒水量的大小,來判斷。
1 #include2 #include3 #include4 #include5
using
namespace
std;
6struct
nodestart;
10bool
operator
< (const node &a,const node &b) //這個東西是用來給優先佇列判斷優先順序用的。很迷,不是很懂。
1114
int judge[4],d,ans[205
];15
int visit[201][201],mark[201][201
]; 16
intuntil_ans(node n)//當一種狀態出現的時候,要對裡面的每一杯水之後的倒水量進行乙個儲存,ans[i]代表當杯子裡出現i公升水時,最小的倒水量。
1724
return0;
25}26void
bfs()
2758}59
}60while(d>=0
)//列舉答案。
6166 d--;//當目標答案沒有的時候,就往前找。(依照題目要求)67}
68}69int
main()
7079
return0;
80 }
uva 10603 倒水問題
劉汝佳說這是一道最短路,可是我怎麼也想不出如何建圖,把問題轉換為最短路問題,我就想自己的辦法。感覺這個題可以用三維dp 每一維代表乙個瓶子 f maxn maxn maxn 狀態轉移我就想 每一次倒水一定要把乙個倒完或把另乙個裝滿才有意義,因為只有這樣三個瓶的水量才知道 所以可以根據這個進行狀態轉移...
Fill BFS 優先佇列 UVA10603
uva 10603 include include include using namespace std struct node friend bool operator node a,node b int a,b,c,d int vis 205 205 b杯和c杯的容量表示一種狀態 int re...
紫書uva 10603 優先佇列 bfs
這個題目其實是暴力的乙個典範,首先題目說了是最小倒水數,也就是總共次數中轉移水的數量,bfs是找最小次數的,因此要用優先佇列來改變優先順序,將最小倒水數優先,然後是處理如果找不到合適的d,我們要把所有能夠找到的值都存放在乙個陣列裡面,然後遍歷一次就可以了,我用的vis陣列是三維的,用來表示第1,2,...