HDU 5459 Jesus Is Here(斐波那契递推 取模)

来源:互联网 发布:tc软件 编辑:程序博客网 时间:2024/05/21 02:49

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5459

比赛的时候把每个c的位置的到下一个c位置的距离算出来,想着怎么去求和,结果卡死在上面了。然后后来就一直在想出题者和cff的关系了。。。


赛后仔细琢磨了一下,觉得这种题就应该从递推的角度去分析,     1A.


首先定义dp[i]表示整数i对应的答案,那么就会有dp[i] = dp[i-2] + dp[i-1] + ?, 关键在于?要怎么解决。  明确“?”表示s[i-2]中所有c到s[i-1]的所有c的距离之和。

我们定义数组cnt[i]表示s[i]中c的个数,dist[i]表示s[i]中所有c到s[i]末尾的距离之和


那么“?”= cnt[i-1] * dist[i-2] + cnt[i-2] * (len[i] - dist[i-1]),特别注意,在dist数组计算距离时,我可以选择包含c或者不包含c,dist[i]包含了c,那么len[i] - dist[i] 就不包含了。

同时易知len[i]也是一个斐波那契数列。


字符串为:s[i] = s[i-2] + s[i-1],   + 表示连接。

有转移方程为:dp[i] = dp[i-2] + dp[i-1] + cnt[i-1] * dist[i-2] + cnt[i-2] * (len[i] - dist[i-1]); 

                      dist[i] = dist[i-1] + dist[i-2] + len[i-1] * cnt[i-2];

      cnt[i] = cnt[i-1] + cnt[i-2];

      len[i] = len[i-1] + len[i-2];

最后注意步步取模。

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <string>#include <cmath>#include <queue>#include <set>#include <stack>using namespace std;const int maxn = 201315;const int mod = 530600414;typedef long long LL;LL dp[maxn];     // 答案LL dist[maxn];   // 所有c到末尾的距离LL cnt[maxn];    // c的个数LL fibo[maxn];   // 长度void init() {    fibo[1] = 1, fibo[2] = 2;    cnt[1] = 1, cnt[2] = 0;    for (int  i = 3; i < maxn; i ++) {        fibo[i] = (fibo[i-1] % mod + fibo[i-2] % mod) % mod;        cnt[i] = (cnt[i-1] % mod + cnt[i-2] % mod) % mod;    }    dist[1] = dist[2] = 0, dist[3] = 2;    for (int i = 4; i < maxn; i ++) {        dist[i] = (dist[i-1] % mod + dist[i-2] % mod + (fibo[i-1] % mod * cnt[i-2] % mod) % mod) % mod;    }    dp[4] = dp[1] = dp[2] = dp[3] = 0;    for (int i = 5; i < maxn; i ++) {        dp[i] = (dp[i-2] % mod + dp[i-1] % mod        + (cnt[i-1] % mod * dist[i-2] % mod) % mod        + (cnt[i-2] % mod * ((fibo[i-1] % mod * cnt[i-1] % mod) % mod - dist[i-1] % mod) % mod) % mod) % mod;    }}int main() {    init();    int cas = 1, t, n;    scanf("%d", &t);    while (t --) {        scanf("%d", &n);        printf("Case #%d: ", cas ++);        printf("%I64d\n", dp[n]);    }    return 0;}



0 0
原创粉丝点击