【Codeforces 1369D】TediousLee
阿新 • • 發佈:2020-07-14
題目連結
翻譯
高度為 \(i+1\) 的一棵 \(RDC\) 樹可以由高度為 \(i\) 的一棵 \(RDC\) 樹通過這樣的規則構造出來:
在高度為 \(i\) 的 \(RDC\) 中,對於只有一個孩子的節點,加上兩個孩子節點,沒有孩子的節點加上一個節點。
問你高度為 \(h\) 的 \(RDC\) 樹有多少個互不重疊的爪型的節點。
題解
遞推題。
動手畫一下的話,會發現高度為 \(h\) 的 \(RDC\) 樹,總是由兩個高度為 \(h-2\) 的 \(RDC\) 樹和一個高度為 \(h-1\) 的 \(RDC\) 以及一個根節點
構成的。
選取爪型的時候,應該儘量讓選擇的爪的根節點在子樹下方,這樣整個樹的根節點就能跟三個子樹的根節點再形成一個爪了。
所以思路就是,設定一個 \(ans[N]\) 表示高度為 \(h\) 的 \(RDC\) 樹能有多少個爪,以及選出的爪中有沒有選樹的根節點。
然後,\(ans[i] = ans[i-2]*2+ans[i-1]+can\), 其中如果高度為 \(i-2\) 和 \(i-1\) 的 \(RDC\) 樹都沒有選根節點作為爪的根的話,
則 \(can=1\),否則 \(can = 0\)。
最後輸入 \(n\), 直接輸出 \(ans[n]*4\) 即可。
程式碼
#include <bits/stdc++.h> #define LL long long using namespace std; const int N = 2e6; const LL MOD = 1e9+7; LL ans[N+10]; bool used[N+10]; int main() { ans[1] = 0;ans[2] = 0; for (int i = 3;i <= N; i++){ if (!used[i-1] && !used[i-2]){ ans[i] = ans[i-2]*2%MOD + ans[i-1] + 1; ans[i] %= MOD; used[i] = true; }else{ ans[i] = ans[i-2]*2%MOD + ans[i-1]; ans[i] %= MOD; } } int T; scanf("%d",&T); while (T--){ int n; scanf("%d",&n); printf("%lld\n",ans[n]*4%MOD); } return 0; }