題目描述 上體育課的時候,小蠻的老師經常帶著同學們一起做游戲。這次,老師帶著同學們一起做傳球游戲。 游戲規則是這樣的:n個同學站成一個圓圈,其中的一個同學手裡拿著一個球,當老師吹哨子時開始傳球,每個同學可以把球傳給自己左右的兩個同學中的一個(左右任意),當老師在此吹哨子時,傳球停止,此時,拿著球沒有 ...
題目描述
上體育課的時候,小蠻的老師經常帶著同學們一起做游戲。這次,老師帶著同學們一起做傳球游戲。
游戲規則是這樣的: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普及組第三題
這題看了一下題解,,
然後,,也不知道為什麼,,,
畫一個表格,下標1標為1
1,0,0
一次迴圈,自己的值變成左邊和右邊的值之和
0,1,1
0,1,1
2,0,0
次數一到,結束操作
不過學到一個方法,對於環形DP,我們可以用pre和nxt數組求前後的祖先,就沒必要特判了,(其實還是特判)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 using namespace std; 6 void read(int & n) 7 { 8 char c='+';int x=0;bool flag=0; 9 while(c<'0'||c>'9') 10 {c=getchar();if(c=='-')flag=1;} 11 while(c>='0'&&c<='9') 12 {x=x*10+(c-48);c=getchar();} 13 flag==1?n=-x:n=x; 14 } 15 int n,m; 16 int dp[101][101]; 17 int pre(int p) 18 { 19 if(p==1) return n; 20 else return p-1; 21 } 22 int nxt(int p) 23 { 24 if(p==n) return 1; 25 else return p+1; 26 } 27 int main() 28 { 29 read(n);read(m); 30 dp[1][1]=1; 31 for(int i=2;i<=m+1;i++) 32 for(int j=1;j<=n;j++) 33 dp[i][j]=dp[pre(i)][pre(j)]+dp[pre(i)][nxt(j)]; 34 printf("%d",dp[m+1][1]); 35 return 0; 36 }