【CF1369D】TediousLee(找規律遞推——計數)

傳送門

  • 題目:
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述
  • 解題思路:
    畫出leve1~5的圖形之後就可以發現,level[i]是由1個level[i-1]和2個level[i-2]再加一個根節點組成的,以level[4]爲例:紅色的爲level[3],綠色的爲level[2]
    在這裏插入圖片描述
    那麼就可以遞推出level[I]的"claw"數:cnt[i]=2cnt[i2]+cnt[i1]cnt[i]=2*cnt[i-2]+cnt[i-1]
    每次取“claw”的時候都是先取最下面的,那麼對於level[i],就可能出現取完level[i-1]和level[i-2]中的claw之後,最頂端還可以再取一個claw。這是因爲level[i-1]和level[i-2]都沒有取到其根節點,在level[i]中恰好這三個根節點加上新的根節點之後組成了一個claw
    如下圖的level[6]:紅圈內的爲level[5],綠圈內的爲level[4],最上面的1、2、3節點又可以構成claw,cnt[i]再+1。
    在這裏插入圖片描述
    add[i]記錄level[I]選取的claw是否包含根節點,爲0則不包含根節點,爲1則包含根節點。
    故答案爲:
    cnt[i]=2cnt[i2]+cnt[i1]cnt[i]=2*cnt[i-2]+cnt[i-1]
    當add[i-1]和add[i-2]都爲0時,cnt[i]++,add[i]=1
    否則,add[I]=0
  • ac代碼:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e6+10;
const ll mod = 1e9+7;
int t, n;
bool add[maxn];
ll cnt[maxn];
int main()
{
    //freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
    add[1] = add[2] = false;
    cnt[1] = cnt[2] = 0;
    for(int i = 3; i <= maxn-10; i++)
    {
        cnt[i] = (2*cnt[i-2]+cnt[i-1])%mod;
        if(!add[i-2]&&!add[i-1]) cnt[i]+=1, add[i] = true;
        else add[i] = false;
    }
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d", &n);
        printf("%lld\n", 4*cnt[n]%mod);
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章