hdu 5459 Jesus Is Here (递推)

题目

思路:
我们用len表示整个字符长度,num表示c的个数,sum表示c各个位置之和,ans来记录答案,我们可以发现len和num都符合斐波那契,sum的话就等于前两个加起来之和再加上前两个的长度乘以前一个的c的个数,表示为sum[i]=sum[i-1]+sum[i-2]+len[i-2]*num[i-1];每次是由前面两个字符串组成那么ans是为前两个之和,因为要算的是每个c之间的距离,把两个连接的地方作为分界线,那么i-1的c到分界线总距离就为num[i-2]*sum[i-1];i-2的c距离分界线的位置就是(len-每个c的位置),化简为(len[i-2]*num[i-1]-sum[i-2),再乘以i-1的c个数就是i-2的c到分界线的总距离,加起来就是答案,注意取模。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int mod=530600414;
ll len[202222],num[202222],sum[202222],ans[202222];
void init()
{
    len[3]=3,num[3]=1,sum[3]=1,ans[3]=0;
    len[4]=5,num[4]=1,sum[4]=3,ans[4]=0;
    for(int i=5;i<=201314;i++)
    {
        len[i]=(len[i-1]+len[i-2])%mod;
        num[i]=(num[i-1]+num[i-2])%mod;
        sum[i]=(sum[i-2]+sum[i-1]+(num[i-1]*len[i-2])%mod)%mod;
        ans[i]=(ans[i-2]+ans[i-1]+sum[i-1]*num[i-2]%mod+((len[i-2]*num[i-2]-sum[i-2])%mod)*num[i-1]%mod)%mod;
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    int t=0;
    init();
    while(T--)
    {
        int n;
        scanf("%d",&n);
        printf("Case #%d: %lld\n",++t,ans[n]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/imzxww/article/details/81319655