1. 程式人生 > >sincerit 勘測(規律題)

sincerit 勘測(規律題)

連結:https://ac.nowcoder.com/acm/contest/280/A
來源:牛客網

題目描述
Actci偶然發現了一個礦洞,這個礦洞的結構類似與一棵二叉樹,Actci發現的礦洞恰好位於根節點處,為了儘快挖掘,Actci找來了她的小夥伴們來幫忙,由於地質原因,每天小夥伴們只能打通到一條到子節點的道路(不消耗時間),也就是說每天一個節點只能向一個子節點建設道路,走一條路需要一天的時間,當發現一條道路後,會有一部分小夥伴選擇留下來繼續勘測,假設小夥伴們有無數個,樹的深度足夠大,問第n天最多共建設幾條道路。
輸入描述:
一行,一個數n。
輸出描述:
一行,一個數表示最多建設的道路數,答案對 10000000007 取模。
示例1
輸入
複製
2
輸出
複製
3
說明
樣例解釋:
設n號點的子節點編號為n×2和n×2+1,根節點編號為1.
第一天1->2,在1,2處留有一部分人,道路數為1。
第二天1->3,2->4,在2,3,4處留有人,道路數為3.
示例2
輸入
複製
100
輸出
複製
6531708670
備註:
資料範圍:
對於100%的資料保證 n ≤ 5×106

比賽的時候一直畫圖可是還是沒找出來,哭
根據題目畫圖或者是打表都能發現規律。容易得到答案的遞推方程為 a[i] = a[i − 1] ∗ 2 − a[i − 3]。直接進行遞推即可。當然
也有其他找規律的方法。時間複雜度 O()。注意當 n = 1 或 n = 2 時的特殊情況。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
#define LL long long
LL n,a[5000000],mod=1e10+7; int main() { a[1]=1;a[2]=3; scanf("%lld",&n); if(n==1) { printf("1"); return 0; } if(n==2) { cout<<3; return 0; } for(LL i=3;i<=n;i++) { a[i]=a[i-1]*2-a[i-3]; a[i]=(a[i]+mod)%mod; 1 } cout<<a[n]; }