原题连接
php
由k范围,咱们寻找线性算法,能够从题中给出的k == 7的例子来分析,以下图
ios
能够看到,因为7余2等于1,而1不可分解,因此每一行都有一个1,因此显然,咱们若是给7减去1以后,结果将仍然是6种,因此咱们能够发现,k为奇数时的结果就是k - 1的结果。
算法
而后咱们抛开最左边的一列1,从下往上看能够发现,第5 6行的全部数能够都除以2,而后得((1 1 1),(1 2)),这正是3的分解结果
spa
而再往上看1234行,咱们发现左边两列都是1,能够看作是第五行中,一个2分解的结果,因而忽略这两列,而后能够发现,从(1,1,1,1)到(4)正是4的分解结果,也就是6 - 2(由于忽略了两行1)的结果
code
考虑k等于其余偶数时,咱们能够发现上述状况是必定会有的 —— 咱们老是会分出一个最小值为2的序列,而后这个序列整体除以2,就是k / 2的分解结果,而后咱们将其中的一个2分解为2个1, 而后剩下的就是k - 2的分解结果,这样就包含了所有状况了
blog
因此k为奇数时, F[k] = F[k - 1]的答案,而k为偶数时,F[k] = F[k >> 1] + F[k - 2]
get
这道题有提到single line,可是仍然有多组数据
string
虽然题目要求后9位,可是在此题中直接%1e9是没有问题的,多是出题人没有想到
it
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define lowbit(x) (x&(-x)) using namespace std; const long long modd = 1000000000; long long ff[1000005]; int n; int main() { ff[0] = 1; for (long long j = 1; j <= 1000000; ++j) { if (j & 1) { ff[j] = ff[j - 1]; } else { ff[j] = ((ff[j] + ff[j - 2]) % modd + ff[j >> 1]) % modd; } } while (scanf("%d", &n) == 1) { printf("%lld\n", ff[n]); } return 0; }