题目链接: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 }