目錄
漢諾塔題意:
思路:**:
放蘋果思路:
特殊情況:
終止條件:
**:網圖:
漢諾塔是一種古老的遊戲。 一共3個柱子,標號為1,2,3 1號柱子有從大到小一共n個盤子。
每次移動最上方的乙個盤子,可以移動到其他的柱子。 任何乙個盤子,都不能疊在比它更小的盤子的上方。 請把盤子從1號柱子,全部移動到3號柱子。
只有乙個的時候: 從a—>c即可。
只有兩個的時候:先將最上面從a-->b,再將最大的從a—>c,再將b的移到c。
三個的時候:先將最上面兩個用上面最有兩個的情況移動到b中,此時c為中轉柱,b為目標柱。再將最大的也就是第三個從a—>c,再將b的兩個同樣方式由b出發移動到c。 (
步數最小原因:若想最大的先進入c,只能讓上面的兩個進入b騰出位置,也就是對應兩個的時候,然後再將b的兩個移動到c,由此也可推出dp[i]=2*dp[i-2]+1); ……
n個的時候,先將上面的(n-1)移動b,然後再將第n個移動到c,再將b的(n-1)個移動到c。而(n-1)如何移動在上面已經遞推出,也就是也n的移動方式、思維方式想用,不同的只是起始柱、中轉柱、目標柱的不同。進而得到遞迴的核心思想:
分解。把乙個很複雜的問題使用同乙個策略將其分解為較簡單的問題
,如果這個的問題仍然不能解決則再次分解
,直到問題能被直接處理為止。
dfs(n,a,b,c)
下層遞迴dfs(n-1,a,c,b);-----此處可加語句記錄路徑,也就是那個移動起始柱最下面的-----------------------printf("move %d from %c to %c\n",n,a,c);-------dfs(n-1,b,a,c);
終止條件,n==1的時候 printf("move %d from %c to %c\n",n,a,c); return;
#include//dp[i] = dp[i-1]*2+1; dp[i-1]從1-->2 2-->1分別為dp[i-1]次 所以為2倍,然後加上最大塊從1-->3;
分情況考慮,因為無順序可言,對某乙個盤子放與不放意義不大。對全放和至少乙個不妨考慮。
dfs(m,n)
如果至少乙個不放,就是dfs(m,n-1),否則就先都放上乙個dfs(m-n,n);這樣就轉化為目前為止的n中至少乙個放超過乙個,
n>m 肯定有n-m空盤子,因為不考慮順序,此時=dfs(m,m);
n==1||m==0即只剩下乙個盤子全放裡面和沒有剩下的蘋果剩下的盤子都不放,return 1;
#include#include#include#include#include#include#include#includeusing namespace std;
typedef long long ll;
const int maxn = 1e6+50;
int dfs(int m,int n)
int main()
return 0;
}
遞迴 放蘋果
遞迴 includeusing namespace std int count int m,int n int main 執行結果 enter n case 2enter two intengers 7 3the total path is 8 enter two intengers 10 8 th...
遞迴 放蘋果
問題描述 把 m 個同樣的蘋果放在n 個同樣的盤子裡,允許有的盤子空著不放,問共有多少 種不同的分法?用k 表示 注意 5,1,1 和1,5,1 是同一種分法。輸入資料 第一行是測試資料的數目t 0 t 20 以下每行均包含兩個整數m 和n,以 空格分開。1 m,n 10。輸出要求 對輸入的每組資料...
遞迴 放蘋果
問題描述 把 m 個同樣的蘋果放在n 個同樣的盤子裡,允許有的盤子空著不放,問共有多少 種不同的分法?用k 表示 注意 5,1,1 和1,5,1 是同一種分法。輸入資料 第一行是測試資料的數目t 0 t 20 以下每行均包含兩個整數m 和n,以 空格分開。1 m,n 10。輸出要求 對輸入的每組資料...