zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    如何处理消息堆积
    如何避免消息的重复发送
    内存泄漏和内存溢出的关系
    数据挖掘
    servlet
    数据驱动安全需三大核心新技术
    JS 入门经典 第三章 判断、循环和函数
    JS 高级程序设计 第三章
    JS入门经典
    JS高级程序设计1-2章
  • 原文地址:https://www.cnblogs.com/edmunds/p/13216653.html
Copyright © 2011-2022 走看看