微软2016校园招聘9月在线笔试C.Fibonacci

#1239 : Fibonacci
时间限制: 10000ms
单点时限: 1000ms
内存限制: 256MB

描述

Given a sequence {an}, how many non-empty sub-sequence of it is a prefix of fibonacci sequence.

A sub-sequence is a sequence that can be derived from another sequence by deleting some elements without changing the order of the remaining elements.

The fibonacci sequence is defined as below:

F1 = 1, F2 = 1

Fn = Fn-1 + Fn-2, n>=3

输入

One line with an integer n.

Second line with n integers, indicating the sequence {an}.

For 30% of the data, n<=10.

For 60% of the data, n<=1000.

For 100% of the data, n<=1000000, 0<=ai<=100000.

输出

One line with an integer, indicating the answer modulo 1,000,000,007.

样例提示

The 7 sub-sequences are:

{a2}

{a3}

{a2, a3}

{a2, a3, a4}

{a2, a3, a5}

{a2, a3, a4, a6}

{a2, a3, a5, a6}


样例输入
6
2 1 1 2 2 3
样例输出
7

题意:给定一个长度为n的序列然后判断这个序列有多少个子序列是Fibonacci数列的前缀

还是太弱了,一开始以为是个组合数学题。后来看了别人的代码才知道是dp

要得到长度为i的Fibonacci数列的前缀,前面必有i-1的Fibonacci数列的前缀

dp[j][i]表示到i个数为止长度为j的Fibonacci数列的前缀有多少个


状态转移方程 dp[j][i]=dp[j][i-1]+dp[j-1][i-1];(a[i]>1, i表示第i个Fibonacci数列=a[i])

dp[1][i]=dp[1][i-1]+1; dp[2][i]= dp[1][i-1]+d[2][i-1](a[i]=1)


#include
#include
#include
#include
using namespace std;

const int N = 30;
const int M = 1000001;
const int mod = 1000000007;
long long dp[N][M];
int a[M];
mapg;

void debug(int n)
{
    for(int i = 0; i < 30; i++)
        printf("%d ", dp[i][n]);
    printf("\n");
}

int main(void)
{
    int n;
    int i, j;
    g[1] = 2;
    a[1] = a[2] = 1;
    for(i = 3; i < 30; i++)
    {
        a[i] = a[i-1] + a[i-2];
        g[a[i]] = i;
    }
    while(~scanf("%d", &n))
    {
        memset(dp, 0, sizeof(dp));
        for(i = 1; i <= n; i++)  scanf("%d", &a[i]);
        for(i = 1; i <= n; i++)
        {
            for(j = 1; j < 30; j++)
                dp[j][i] = dp[j][i-1];
            int tmp = g[ a[i] ];
            if(!tmp) continue;
            if(tmp == 2)
            {
                dp[1][i] = (dp[1][i] + 1)%mod;
                dp[2][i] = (dp[2][i] + dp[1][i-1])%mod;
            }
            else
            {
                dp[tmp][i] = (dp[tmp][i] + dp[tmp-1][i])%mod;
            }
//            printf("tmp=%d\n", tmp);
//            debug(i);
        }
        long long ans = 0;
        for(i = 1; i < 30; i++) ans = (ans + dp[i][n])%mod;
        printf("%lld\n", ans);
    }
    return 0;
}

你可能感兴趣的:(DP)