題目連結
錯誤程式碼的 \(dfs\) 方式:
void dfs(int u, int cnt)
{
if(u == n) return ;
if(n - u + cnt < m) return ;
if(cnt == m) // 再往下dfs沒有意義了,剪枝
{
dp();
return ;
}
dfs(u + 1, cnt);
del[u] = true;
dfs(u + 1, cnt + 1);
del[u] = false;
}
在這份程式碼中,我們將 if(cnt==m)
的判斷放在了 if(u == n)
和 if(n - u + cnt < m)
之後,這就會導致一個問題,那就是當某次 \(dfs\) 同時滿足 cnt==m
和 u==n
時,會直接先 \(return\) 掉,而不會執行 dp()
,從而漏解
正確的做法應該是,在遞迴當中 \(return\) 時,先 \(return\) 有解的情況,確保走到無解 \(return\) 語句時,一定不會有解。
正確的 \(dfs\) 程式碼
void dfs(int u, int cnt)
{
if(cnt == m) // 再往下dfs沒有意義了,剪枝
{
dp();
return ;
}
if(u == n) return ;
if(n - u + cnt < m) return ;
dfs(u + 1, cnt);
del[u] = true;
dfs(u + 1, cnt + 1);
del[u] = false;
}