見鏈結
這題需要使用手動簡單的模擬一下,原題中的乙個測試用例便是乙個好的例子,傳球只能往左邊或右邊傳,相應的,傳球次數減一,我們深搜這個狀態直到最終傳到第乙個人手裡。於是得到深搜的主要過程:
f[i][j] = dfs( (i+1)%n,j-1 ) + dfs( (i-1 + n)%n,j-1 );
。其中f[i][j]
代表的是經過j
次傳球回到i號人手中
第一次提交的**如下:
#include
#include
using
namespace std;
const
int maxn =35;
int n,m;
int f[maxn]
[maxn]
;//f[i][j] 用於計算"經過j次傳球回到i號人手中"
//計算"經過j次傳球回到i號人手中"
intdfs
(int i,
int j)
intmain()
輸入:
10 29
0輸出:
0
根據上面的問題分析(是程式導致死迴圈而不是測試用例),那麼就應該檢視是否是深搜的過程中沒有及時返回(因為只有不能返回才會導致死迴圈)。那麼是什麼地方會出現無法返回呢?。看dfs()
中的**:
//計算"經過j次傳球回到i號人手中"
intdfs
(int i,
int j)
其中的返回語句只有兩句:
if
(f[i]
[j]!=0)
return f[i]
[j];
if(j ==
0&& i!=0)
return
0;
很清楚,可以看到這裡有乙個自相矛盾的地方。第二個if的返回值是0(表明該次深搜過程的f[i][j]
已經計算好了),但是第乙個if卻是根據f[i][j]!=0
來返回,這就導致上一次計算好的,這次還是會計算遞迴計算,從而導致死迴圈。
將f[i][j]
初始化為-1,然後再根據是否是-1進行返回,就可以順利得出答案了。ac**如下:
#include
#include
using
namespace std;
const
int maxn =35;
int n,m;
int f[maxn]
[maxn]
;//f[i][j] 用於計算"經過j次傳球回到i號人手中"
//計算"經過j次傳球回到i號人手中"
intdfs
(int i,
int j)
intmain()
4 1
0
洛谷 P1057 傳球遊戲
題目描述 上體育課的時候,小蠻的老師經常帶著同學們一起做遊戲。這次,老師帶著同學們一起做傳球遊戲。遊戲規則是這樣的 n個同學站成乙個圓圈,其中的乙個同學手裡拿著乙個球,當老師吹哨子時開始傳球,每個同學可以把球傳給自己左右的兩個同學中的乙個 左右任意 當老師在此吹哨子時,傳球停止,此時,拿著球沒有傳出...
洛谷 P1057 傳球遊戲
題目描述 上體育課的時候,小蠻的老師經常帶著同學們一起做遊戲。這次,老師帶著同學們一起做傳球遊戲。遊戲規則是這樣的 n個同學站成乙個圓圈,其中的乙個同學手裡拿著乙個球,當老師吹哨子時開始傳球,每個同學可以把球傳給自己左右的兩個同學中的乙個 左右任意 當老師在此吹哨子時,傳球停止,此時,拿著球沒有傳出...
P1057 傳球遊戲 洛谷
上體育課的時候,小蠻的老師經常帶著同學們一起做遊戲。這次,老師帶著同學們一起做傳球遊戲。遊戲規則是這樣的 n個同學站成乙個圓圈,其中的乙個同學手裡拿著乙個球,當老師吹哨子時開始傳球,每個同學可以把球傳給自己左右的兩個同學中的乙個 左右任意 當老師在此吹哨子時,傳球停止,此時,拿著球沒有傳出去的那個同...