【CF1369D】TediousLee(找规律递推——计数)

传送门

  • 题目:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 解题思路:
    画出leve1~5的图形之后就可以发现,level[i]是由1个level[i-1]和2个level[i-2]再加一个根节点组成的,以level[4]为例:红色的为level[3],绿色的为level[2]
    在这里插入图片描述
    那么就可以递推出level[I]的"claw"数: c n t [ i ] = 2 ∗ c n t [ i − 2 ] + c n t [ i − 1 ] cnt[i]=2*cnt[i-2]+cnt[i-1] cnt[i]=2cnt[i2]+cnt[i1]
    每次取“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、4节点又可以构成claw,cnt[i]再+1。
    在这里插入图片描述
    add[i]记录level[I]选取的claw是否包含根节点,为0则不包含根节点,为1则包含根节点。
    故答案为:
    c n t [ i ] = 2 ∗ c n t [ i − 2 ] + c n t [ i − 1 ] cnt[i]=2*cnt[i-2]+cnt[i-1] cnt[i]=2cnt[i2]+cnt[i1]
    当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;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值