【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;
}

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