嗨,大家好,今天想跟大家分享一下d105. NOIP 2008 3.传球游戏 這一題的解題想法,歡迎大家一起討論 我的C++程式碼 ``` #include <bits/stdc++.h> using namespace std; #define N 32 int n,m; int dp[N][N]; int main(){ cin>>n>>m; dp[0][1]=1; for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ int left,right; if(j==1) left=n; else left=j-1; if(j==n) right=1; else right=j+1; dp[i][j]=dp[i-1][left]+dp[i-1][right]; } } cout<<dp[m][1]<<endl; } ``` 接著來說一下我的解題思路 1. 首先我設了一個動態規劃的陣列dp,其中dp的功能: dp[傳了幾次][目前位置] = 有幾種方式 換句話說,dp[i][p] 代表傳了 i 次球後,球剛好在 p 號位置的方法數。 2. 然後我把問題簡化,現在我想知道我是怎麼走到 dp[x][y]這一格的,有兩種可能,一種是從y的左邊,往右走一個到y,傳球次數+1 ,或是 y的右邊,往左走一個到y,傳球次數+1 。所以我們可以推出狀態轉移方程 : dp[x][y]=dp[x-1][y的左邊]+ dp[x-1][y的右邊] 3. 接下來我們要處理基底條件(就像一個遞迴數列的開頭),如果沒有它,狀態轉移方程會沒辦法算出正確答案 `dp[0][n] =1 ; //只有一種方式能在傳了0次時在原位` 4. 最後輸出 選了m次後在位置1(也就是回到原位)時的方法次數就大功告成啦 `cout<<dp[m][1]<<endl;` 在實作時需要注意的事項: 1. 題目中有說道,遊戲規則是所有人圍成一個圓圈,假設今天有1,2,3,4,5個人圍成圓圈,那麼這時候5號位置的右邊那位是1號位置,而1號位置的人左邊是5號位置,所以在寫的時候要記得確保圓環的結構喔
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up