cf1369D---找规律,递推

题目链接:https://codeforces.com/problemset/problem/1369/D

简单题意:给定一棵树的生成规则:每一个level,对于每个节点,若没有子节点,则增加一个;若有一个子节点,则再增加两个;其他情况忽略该节点。求第i个level中,最多的不相交爪的个数(详细定义见原题)。

画图,发现一个简单的递推式: f[i]=2*f[i-2]+f[i-1],但是后来发现当n=6和n=3的时候结果不一样,因为此时可以取根节点,然后对这两种情况特判了一下就过了,一开始只觉得大概是对的......后来看了别人的博客。首先如果要取出的爪数最多,肯定尽量从下往上取。画画图可以知道n=4,n=5是取不到根节点的,当n=6时,由于顶部多出了一个爪n=4和n=5的子树取不到它的节点,所以结果要+1。类似的,当递推式中i%3=0时,i-1和i-2的子树都不会影响到顶端的爪,所以f[i]=2*f[i-2]+f[i-1]+1;而当i%3≠0时,i-1和i-2的子树会有模3余0的,从而会影响到顶部的爪,结果就是f[i]=2*f[i-2]+f[i-1]。附上一张图,来源于:https://blog.csdn.net/mrcrack/article/details/106938912

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 
 5 const int maxn=2e6;
 6 const int mod=1e9+7;
 7 
 8 ll f[maxn+10];
 9 int t,n,i,j,k;
10 
11 int main(){
12     f[0]=f[1]=f[2]=0;
13     for (i=3;i<=maxn;i++){
14       if (i%3==0) f[i]=(f[i-1]+2*f[i-2]+1)%mod; //*
15       else f[i]=(f[i-1]+2*f[i-2])%mod;
16     }
17     cin>>t;
18     while (t--){
19       cin>>n;
20       cout<<(f[n]*4)%mod<<endl;
21     }
22     //system("pause");
23     return 0;
24 }
cf1369D

 

posted @ 2020-06-30 23:12  coastal_taipan  阅读(198)  评论(0编辑  收藏  举报