動態規劃-擊鼓傳花
阿新 • • 發佈:2018-12-09
【題目】
學校聯歡晚會的時候,為了使每一個同學都能參與進來,主持人常常會帶著同學們玩擊鼓傳花的遊戲。遊戲規則是這樣的:n個同學坐著圍成一個圓圈,指定一個同學手裡拿著一束花,主持人在旁邊背對著大家開始擊鼓,鼓聲開始之後拿著花的同學開始傳花,每個同學都可以把花傳給自己左右的兩個同學中的一個(左右任意),當主持人停止擊鼓時,傳花停止,此時,正拿著花沒傳出去的那個同學就要給大家表演一個節目。
聰明的小賽提出一個有趣的問題:有多少種不同的方法可以使得從小賽手裡開始傳的花,傳了m次以後,又回到小賽手裡。對於傳遞的方法當且僅當這兩種方法中,接到花的同學按接球順序組成的序列是不同的,才視作兩種傳花的方法不同。比如有3 個同學1號、2號、3號,並假設小賽為1號,花傳了3次回到小賽手裡的方式有1->2->3->1和1->3->2->1,共2種。
輸入
輸入共一行,有兩個用空格隔開的整數n,m(3<=n<=30,1<=m<=30)
樣例輸入
3 3
輸出
輸出共一行,有一個整數,表示符合題意的方法數
樣例輸出
2
時間限制
C/C++語言:1000MS其它語言:3000MS
記憶體限制
C/C++語言:65536KB其它語言:589824KB
【solution】
package dynamic_planing;
import java.util.Scanner;
/**
* 思路:
* 設n個人第m次回到小賽手裡的情況為dp[m ][n]
* dp[m][n]等於第m-1次傳遞到小賽左右兩邊的人的情況之和,即 dp[m][n] = dp[m-1][(n-1+n)%n] + dp[m-1][(n+1)%n]
* 邊界值:
* dp[1][2] = 1 dp[1][2] = dp[0][1] + dp[0][3] ----------> dp[0][1] = 1
* dp[1][n] = 1 dp[1][n] = dp[0][1] + dp[0][n-1] ----------> dp[0][1] = 1 其餘dp[0][i] = 0;
* 真正的邊界值:
* dp[0][1] = 1 dp[0 ][i != 1] = 0;
*/
public class TransmitFlower {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
sc.close();
int[][] dp = new int[m+1][n+1];
dp[0][1] = 1;
//dynamic planing
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if(j == 1){
dp[i][j] = dp[i-1][n] + dp[i-1][j+1];
}else if(j == n){
dp[i][j] = dp[i-1][j-1] + dp[i-1][1];
}else{
dp[i][j] = dp[i-1][j-1] + dp[i-1][j+1];
}
}
}
System.out.println(dp[m][1]);
}
}