洛谷 P1057 傳球遊戲 題解
阿新 • • 發佈:2017-08-20
輸入 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 傳球遊戲 題解