题目链接:[HDU 5459]Jesus Is Here[递推][实现]
题意分析:
问给定的第n个字符串中,所有c之间的距离之和是多少?(
s[i]=s[i−2]+s[i−1]
)
解题思路:
我们设f[i]为答案,那么由定义:
f[i]=f[i−2]+f[i−1]+(跨越两串的距离之和)
跨越两串的距离和怎么求呢?
设置一个sum[i]数组代表,s[i]中到c到结尾的距离之和,再设置一个cnt[i]数组,代表s[i]中c的个数。有了这个定义之后,那么就有:
跨越两串的距离和=cnt[i−1]∗sum[i−2]+cnt[i−2]∗(cnt[i−1]∗len[i−1]−sum[i−1])
其中len[i]代表s[i]的长度。
最后注意下取模,就能得出答案了。
个人感受:
跨越两串的距离只和,真心不知道怎么求,看了网上的数组定义后,才渐渐有了思路。
具体代码如下:
#include<cstdio>
#define ll long long
const int MOD = 530600414;
const int MAXN = 201320;
ll f[MAXN], cnt[MAXN], len[MAXN], sum[MAXN];
void init()
{
f[1] = f[2] = f[3] = 0;
len[1] = 1, len[2] = 2, len[3] = 3;
cnt[1] = 1, cnt[2] = 0, cnt[3] = 1;
sum[1] = sum[2] = 0, sum[3] = 3;
for (int i = 4; i <= 201314; ++i)
{
len[i] = (len[i - 2] + len[i - 1]) % MOD;
cnt[i] = (cnt[i - 2] + cnt[i - 1]) % MOD;
sum[i] = (sum[i - 2] + cnt[i - 2] * len[i - 1] + sum[i - 1]) % MOD;
f[i] = (f[i - 2] + f[i - 1]
+ (cnt[i - 1] * sum[i - 2]) % MOD
+ (cnt[i - 2] * ((cnt[i - 1] * len[i - 1]) % MOD + MOD - sum[i - 1])) % MOD) % MOD;
}
}
int main()
{
int t, n;
init();
for (int kase = scanf("%d", &t); kase <= t; ++kase)
{
scanf("%d", &n);
printf("Case #%d: %lld\n", kase, f[n]);
}
return 0;
}