【网易有道10年编程赛 网络热身赛】第三题 Sibonacci

 

菲波那切数列可以用下列的式子表示: 
    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 

 

/*

这题是一个简单的递归问题,难点在于对浮点数整型化的处理,这样可以降低复杂度,从而利用备忘录减少时间开销

由于递归式中要减去一个3.14,小数点后两位,所以对所有数据×1000,进行整型化

*/

#include <iostream> #include <stdio.h> #include <stdlib.h> #define minv(a, b) ((a) <= (b) ? (a) : (b)) #define maxv(a, b) ((a) >= (b) ? (a) : (b)) #define MAX_N 1110005 //为了简化小数的处理,将所有数 × 1000,这样,数据范围变成了0 ~ 1000000 #include <string> #define EPS 1e-8 //浮点精度 using namespace std; int record[MAX_N]; //记录结果,备忘录 //递归计算 int getVal(int x) { //小于0,返回0 if(x < -EPS) return 0; // 0 <= x < 1返回1 if(x >= -EPS && x - 1000 < EPS) return 1; //已经计算过,直接返回 if(record[x] != 0 ) return record[x]; //否则递归计算,由于所有数都×1000,所以递归式里的, 1, 3.14分别变成了1000, 3140 int res1 = getVal(x - 1000) % 1000000007, res2 = getVal(x - 3140) % 1000000007; return record[x] = (res1 + res2) % 1000000007; } int main() { int T; double x; scanf("%d", &T); for(int i = 0; i < MAX_N; i++) record[i] = 0; while(T--) { scanf("%lf", &x); int res = getVal(x * 1000); printf("%d/n", res); } return 0; } 

 

你可能感兴趣的:(【网易有道10年编程赛 网络热身赛】第三题 Sibonacci)