#include "stdafx.h" /* 描述 菲波那切数列可以用下列的式子表示: f(1)=1 f(2)=1 f(n)=f(n-1)+f(n-2) (n>=3) 现在我们根据这个规则定义另一种数列 命名为"辛波那切数列", 它是这样定义的: s(x)=0 (x<0) s(x)=1 (0<=x<1) s(x)=s(x-1)+s(x-3.14) (x>=1) 现在需要计算出s(x) MOD 1000000007的值。 输入 第一行有一个正整数T表示有T组测试数据。 接下来T行,每行包含一个数x。 其中 T<=10000, -1000.0<=x<=1000.0 输出 有T行,依次输出每组数据的结果。 样例输入 3 -1 0.667 3.15 样例输出 0 1 2 */ long Sibonacci( float x //-1000.0<=x<=1000.0 ){ if (x < 0.0f){ return 0L; } else if (x <= 1.0f) { //for quick because S(x=1) also =1 return 1L; } //original method //return Sibonacci(x - 1.0f) + Sibonacci(x - 3.14f); //improve method 1 for reducing momentary memory-payload-peak-value long r; //根据题意s(x)=0 (x<0),如果x是整数,则计算f(x)=f(x-1)所以分支的返回结果=0(所以和=0),因为x-1到最后 x必然=0 //根据题意s(x)=1 (0<=x<1),如果x有小数,则计算分支 f(x)=f(x-1) 的结果=1,因为x-1到最后 x必然只剩小数 //一个S(x)=S(x-1)+S(x-3.14),S(x-1)又可以看做=S(x-1-1)+S(x-1-3.14) //所以可以把 x 看作是 x-(A或B)-(A或B)的排列,只要排列中多个AB的和小于x,同时大于x-1,其它无意义(不是结果为0无意义,就是未细分到最后) //说到最后,就是统计计算有多少AB的排列组合P(AB)(未定义数量),只要求这些AB之和小于x,并且与X之差小于1 //有点类似背包,尽可能填满一个空间,不可再装,使剩余空间并且小于1个可装填单位之内,便是一种填补方法 //这里A和B = 1 和 3.14,空间=X小于=1000 //具体到此题,是说所有任何"1"和"3.14"的排列的数量,要求排列中组成的数之和要在 999< sum <=1000 之间 //对于求1,3.14排列,可以先求组合,一个"3.14"量相当于三个"1"的量 //有了正确的组合配比(就是sum在范围内),然后拿现成公式求排列数,P //逐个递减 "3.14",递增"1", //到最后一定有一个精确的结果, //限于时间宝贵,浪费生命,又不是专门研究算法的数学家,就不给出实现代码了,算法复杂度应该是 O(n) return r; } int _tmain(int argc, _TCHAR* argv[]) { float x = 1000.0f; const float MOD = 1000000007.0f; long r = Sibonacci(x); printf("%ld", &r); return 0; }