C語言 收集硬幣(動態規劃,回溯)

2021-10-04 15:10:52 字數 3431 閱讀 6264

回溯法的思路及分析:

完整**:

輸入及結果示例:

路徑圖示例:

在m*n的方格中放有一些硬幣,每格的硬幣數目最多為乙個,從方格左上方開始收集盡可能多的硬幣並把它們帶到右下方的單元格。每一步只可以從當前的位置向右移動一格或向下移動一格。當遇到乙個有硬幣的單元格時,就會將這枚硬幣收集起來。問怎樣移動才能收集到最多的硬幣?

我們來舉個例子分析分析:

如果硬幣分布情況如圖:

簡化分布後(有硬幣為 『1』,無硬幣 『0』):1

2345

6100

0010

2010

1003

0001

0140

0100

1510

0010

我們假設 f(i,j)為走到(a,b)所能收集到的最大硬幣數。單元格(a,b)可以經由上方(a-1,b)和左側單元格(a,b-1)到達。單元格(a-1,b)對應的最大硬幣數為 f(a-1,b),單元格(a,b-1)對應的最大硬幣為 f(a,b-1)。

關鍵方程:

f(i,j)=max + arr[ i ][ j ]注:(1) max 為自定義函式,用來選取較大的值。

(2) arr[ i ][ j ] 表示第 i 行,第 j 列是否有硬幣,有則為 『1』 ,否則為 『0』。

利用上述公式,我們可以逐行或則逐列對 m*n 的表進行填充。

f(i,j)的情況如下:1

2345

6100

0011

2011

2223

011334

4012

3355

1123

45

注:填寫規則:以圖中所標記的 『3』 為例,在只能往右和往下走的情況下,選取 『3』 上面和左面相鄰的方格中最大的乙個,如圖中選取上面的 『2』 ,由於在第 3 行,第 4 列的位置有乙個硬幣,所以上面的 『2』 需要加 『1』 ( arr[ 3 ][ 4 ] = 1 ),以此類推,課填充所有**。

結合以上分析寫出關鍵**:
void

findmax()

//m 代表行, n 代表列

}printf

("\n最多蒐集 %d 個硬幣。\n"

,f[m]

[n])

;//注意,輸出並不是f(i,j)!!!而是表單上位於第m行,第n列的值!!!

}

回溯法(探索與回溯法)是一種選優搜尋法,又稱為試探法,按選優條件向前搜尋,以達到目標。

通過回溯法我們可以有以下的判斷:

(1):f(i-1,j)>f(i,j-1)時,到達單元格(i,j)的最優路徑肯定來自上面的單元格。

(2):f(i-1,j)< f(i,j-1)時,到達單元格(i,j)的最優路徑肯定來自左面的單元格。

(3):f(i-1,j)= f(i,j-1)時,到達單元格(i,j)的最優路徑可以來自上面或左面的任一單元格。

結合以上分析寫出回溯的關鍵**:

void

huisu()

else

}for

(int i=

1;i<=m;i++

)//回溯完成後對儲存路徑的h進行遍歷,並輸出路徑。

for(

int j=

1;j<=n;j++)}

}

#include

#define max 10

int m,n;

//方格的行和列

int arr[max]

[max]

;//儲存原始方格元素

int f[max]

[max]

;//儲存收集到的最大硬幣數

int h[max]

[max]

;//進行回溯操作時,儲存路線座標

void

huisu()

;void

findmax()

;int

max(

int a,

int b);/*

方格為:

0 0 0 0 1 0

0 1 0 1 0 0

0 0 0 1 0 1

0 0 1 0 0 1

1 0 0 0 1 0

*/void

main()

}findmax()

;printf

("收集的路線為:\n");

huisu()

;}intmax

(int a,

int b)

void

findmax()

}printf

("\n最多蒐集 %d 個硬幣。\n"

,f[m]

[n]);}

void

huisu()

else

}for

(int i=

1;i<=m;i++

)for

(int j=

1;j<=n;j++)}

}

請輸入方格的行數和列數:(空格隔開)56

請輸入第1行的6個數:(只能出現0或1)0

0001

0請輸入第2行的6個數:(只能出現0或1)0

1010

0請輸入第3行的6個數:(只能出現0或1)0

0010

1請輸入第4行的6個數:(只能出現0或1)0

0100

1請輸入第5行的6個數:(只能出現0或1)1

0001

0最多蒐集 5 個硬幣。

收集的路線為:

2020 10 01 動態規劃 回溯

框架 初始化 base case dp 0 0 base 進行狀態轉移 for 狀態1 in 狀態1的所有取值 for 狀態2 in 狀態2的所有取值 for dp 狀態1 狀態2 求最值 選擇1,選擇2.509.斐波那契數 var fib function n return cur 322.零錢兌...

01揹包(動態規劃(回溯))

include 所謂動態規劃,就是分治策略加上不同的區域之間相互影響,如何從區域性最優解,到全域性最優解,這便是我們所關注的重點,因為還是分割成一塊一塊的,遞迴入手更好去理解。現有n件物品,其中第i件物品的重量為w i 價值為v i 有一容量為j的揹包,求在不超過揹包容量的情況下,使取得的商品的價值...

動態規劃回溯 dp回溯查詢可行解

題目背景 三水非常喜歡吃水果撈,但是每次她都吃不完一整盒果撈,就會吃飽,而吃得太飽會不舒服。對於果撈裡的每一塊水果,三水都有不同的喜愛程度。她希望在不吃得太飽的基礎上,可以盡可能多地吃掉自己喜歡的水果。你能幫幫她嗎?題目描述 吃飽的時候三水的飽腹感為w w 10000 w w 10000 w w 1...