hihocoder1239(递推)

来源:互联网 发布:php个人博客网站代码 编辑:程序博客网 时间:2024/06/05 04:05

链接:点击打开链接

题意:给出N个数,求其中子序列是斐波那契的前缀的种数

代码1:

#include <queue>#include <vector>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const long long MOD=1000000007;long long f[30],a[1000005],dp[1000005][25];int main(){    long long n,i,j,ans;    f[1]=1,f[2]=1;    for(i=3;i<=25;i++)    f[i]=f[i-1]+f[i-2];    while(scanf("%lld",&n)!=EOF){               //dp[i][j]表示到第i位,以dij个fib结尾的种数        memset(dp,0,sizeof(dp));                //所以递推式就是dp[i][j]=dp[i-1][j]+dp[i-1][j-1];        for(i=1;i<=n;i++){                      //时间复杂度O(N*25)            scanf("%lld",&a[i]);            dp[i][1]=dp[i-1][1];                //其实这个是一个很容易的递推,而且这个复杂度也可以过,            if(a[i]==1)                         //但明显有更好的方法,我们通过观察可以发现很容易就能            dp[i][1]=(dp[i][1]+1)%MOD;          //改写成一维,只要注意结尾是1的就可以,然后处理出每个        }                                       //数是fib中的第几位,也就同时把时间和空间的复杂度都变        for(i=1;i<=n;i++){                      //为O(N)            for(j=1;j<=25;j++){                dp[i][j]=dp[i-1][j];                if(a[i]==f[j])                dp[i][j]=(dp[i][j]+dp[i-1][j-1])%MOD;            }        }        ans=0;        for(i=1;i<=25;i++)        ans=(ans+dp[n][i])%MOD;        printf("%lld\n",ans);    }    return 0;}

代码2:

#include <queue>#include <vector>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const long long MOD=1000000007;long long f[30],id[200005],a[1000005],dp[1000005];int main(){    long long n,i,j,op,ans;    memset(id,0,sizeof(id));    f[1]=1,f[2]=1,id[1]=2;    for(i=3;i<=25;i++){        f[i]=f[i-1]+f[i-2];        id[f[i]]=i;    }    while(scanf("%lld",&n)!=EOF){        memset(dp,0,sizeof(dp));        for(i=1;i<=n;i++)        scanf("%lld",&a[i]);        dp[1]=(a[i]==1);        for(i=1;i<=n;i++){            op=id[a[i]];            if(op==2){                          //要注意更新顺序                dp[2]=(dp[2]+dp[1])%MOD;                dp[1]=(dp[1]+1)%MOD;            }            else if(op!=0)            dp[op]=(dp[op]+dp[op-1])%MOD;        }        ans=0;        for(i=1;i<=25;i++)        ans=(ans+dp[i])%MOD;        printf("%lld\n",ans);    }    return 0;}

原创粉丝点击