1. 程式人生 > 實用技巧 >【Codeforces 1369D】TediousLee

【Codeforces 1369D】TediousLee

題目連結

點我呀

翻譯

高度為 \(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;
}