1. 程式人生 > >洛谷 P1057 傳球遊戲 題解

洛谷 P1057 傳球遊戲 題解

輸入 ron 轉移 ring printf 序列 www. algo ==

此文為博主原創題解,轉載時請通知博主,並把原文鏈接放在正文醒目位置。

題目鏈接:https://www.luogu.org/problem/show?pid=1057

題目描述

上體育課的時候,小蠻的老師經常帶著同學們一起做遊戲。這次,老師帶著同學們一起做傳球遊戲。

遊戲規則是這樣的:n個同學站成一個圓圈,其中的一個同學手裏拿著一個球,當老師吹哨子時開始傳球,每個同學可以把球傳給自己左右的兩個同學中的一個(左右任意),當老師再次吹哨子時,傳球停止,此時,拿著球沒有傳出去的那個同學就是敗者,要給大家表演一個節目。

聰明的小蠻提出一個有趣的問題:有多少種不同的傳球方法可以使得從小蠻手裏開始傳的球,傳了m次以後,又回到小蠻手裏。兩種傳球方法被視作不同的方 法,當且僅當這兩種方法中,接到球的同學按接球順序組成的序列是不同的。比如有三個同學1號、2號、3號,並假設小蠻為1號,球傳了3次回到小蠻手裏的方 式有1->2->3->1和1->3->2->1,共2種。

輸入輸出格式

輸入格式:

輸入文件ball.in共一行,有兩個用空格隔開的整數n,m(3<=n<=30,1<=m<=30)。

輸出格式:

輸出文件ball.out共一行,有一個整數,表示符合題意的方法數。

輸入輸出樣例

輸入樣例#1:
3 3
輸出樣例#1:
2

說明

40%的數據滿足:3<=n<=30,1<=m<=20

100%的數據滿足:3<=n<=30,1<=m<=30

2008普及組第三題

分析:

初始狀態f[0][1] = 1

每次轉移時就把左右兩側的方案數加上來,註意1和n要特殊處理。

AC代碼:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstring>
 5 
 6 const int MAXN = 105;
 7 
 8 inline void read(int &x)
 9 {
10     char ch = getchar(),c = ch;x = 0;
11     while(ch < 0 || ch > 9) c = ch,ch = getchar();
12 while(ch <= 9 && ch >= 0) x = (x<<1)+(x<<3)+ch-0,ch = getchar(); 13 } 14 15 int f[50][50]; 16 //f[i][j] 第i回合結束,球在第j人手上的情況數 17 18 int main() 19 { 20 int n,m; 21 read(n),read(m); 22 f[0][1] = 1; 23 for(int i = 1;i <= m;++ i) 24 for(int j = 1;j <= n;++ j) 25 { 26 if(j == 1) f[i][j] += f[i-1][j+1] + f[i-1][n]; 27 else if(j == n) f[i][j] += f[i-1][j-1] + f[i-1][1]; 28 else f[i][j] += f[i-1][j-1] + f[i-1][j+1]; 29 } 30 printf("%d\n",f[m][1]); 31 return 0; 32 }

洛谷 P1057 傳球遊戲 題解