HDU 5459 Jesus Is Here(斐波那契递推 取模)
2015-09-19 21:08
183 查看
题目链接: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];
最后注意步步取模。
比赛的时候把每个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 ); } return 0; }
相关文章推荐
- iOS 限制图片的缩放比例 设置捏合手势的缩放比例
- 对老师推荐文章的认识
- 搭建双塔
- Andriod Studio debug.keystore(默认)和如何生成自定义的keystore 以及如何生成数字签名
- calloc和malloc/free以及new/delete相关知识
- HMM前向算法,维比特算法,后向算法,前向后向算法代码
- ecshop在PHP 5.4以上版本各种错误问题处理
- iOS UIAlertController 弹框 (ios 9.0 后代替了UIAlertView弹框 和 UIActionSheet下弹框)
- 【NOI2012】随机数生成器
- 杭电acm--2097
- NOIP2010-普及组初赛C语言解析
- 对Git的认识
- wxWidgets Tips: 用 Visual Studio 2015 编译 wxWidgets
- 打开Voice Over时,CATextLayer的string对象兼容NSString和NSAttributedString导致的Crash(一现象)
- linux挂载samba共享文件夹
- 易忘知识整理
- 我已在路上
- easyui datagrid学习笔记
- 搜狐面试总结
- Number of Digit One -- leetcode