DP + math 之 Codeforces 126D - Fibonacci Sums
来源:互联网 发布:js怎么创建二维数组 编辑:程序博客网 时间:2024/06/10 18:40
// [7/12/2014 Sjm]/*题目:By the given number n determine the number of its possible different decompositions into Fibonacci sum. 前提:1) F[86] 是 >=10^18 的最大Fibonacci数;2)(由Fibonacci数列的构造式决定,举几个例子就可以知道了)假设的Fibonacci数的下标区间为[m, n),包括 m, 对n进行拆分,其分解的数目是: (n-m)>>1假设的Fibonacci数的下标区间为(m, n),不包括 m, 对n进行拆分,其分解的数目是: (n-m-1)>>1 思路:用 N 减去(与N相等或小于N)的最大的Fibonacci数,并将得到的值付给N,不断循环,直至 N 为零。(保证拆分出来的Fibonacci数的数目是最少的,使 dp 时不会漏掉情况) 将取得的所有Fibonacci数从小到大排列出来, 存储于 get_index[] (存储的是所取得的Fibonacci的标号) 状态:dp[i][1]: 在拆分 N 时,已选取 get_index[i] 位置所代表的Fibonacci数, 此情况下不同分解的数目(言外之意是:不可以将 get_index[i] 位置所代表的Fibonacci数拆了)dp[i][0]: 在拆分 N 时,没有选取 get_index[i] 位置所代表的Fibonacci数,此情况下不同分解的数目(言外之意是:可以将 get_index[i] 位置所代表的Fibonacci数用其他Fibonacci数拆了) 分析: 1) dp[i][1]的情况: 由于不可以将 get_index[i] 位置所代表的Fibonacci拆数了,故决定dp[i][1]的因素是 get_index[i-1] 位置所代表的Fibonacci数2) dp[i][0]的情况:此时 get_index[i] 位置所代表的Fibonacci数可拆,故在 dp[i-1][0] 的基础上: 需要分解的Fibonacci数下标区间为 [get_index[i-1], get_index[i])在 dp[i-1][1] 的基础上: 需要分解的Fibonacci数下表区间为 (get_index[i-1], get_index[i])(求解方法,参见前提)至于为什么这样分解,可以看一下这样几个例子(关键看从上到下的排列方式):例1:13 = 13 例2:16 = 13 + 313 = 8 + 516 = 13 + 2 + 113 = 8 + 3 + 216 = 8 + 5 + 316 = 8 + 5 + 2 + 1决策:初始状态: dp[0][1] = 1, dp[0][1] = (get_index[i] - 1)>>1;dp[i][1] = dp[i - 1][1] + dp[i - 1][0];dp[i][0] = dp[i - 1][0] * ((get_index[i] - get_index[i - 1]) >> 1) + dp[i - 1][1] * ((get_index[i] - get_index[i - 1] - 1) >> 1); */#include <iostream>#include <cstdlib>#include <cstdio>#include <algorithm>using namespace std;typedef __int64 int64;const int MAX = 90;int64 F[MAX];int get_index[MAX];int64 dp[MAX][2];void Fib(){F[0] = 1;F[1] = 1;for (int i = 2; i < 87; ++i) {F[i] = F[i - 1] + F[i - 2];}}int64 Solve(int len){dp[0][1] = 1;dp[0][0] = (get_index[0] - 1) >> 1;for (int i = 1; i < len; ++i) {dp[i][1] = dp[i - 1][1] + dp[i - 1][0];dp[i][0] = dp[i - 1][0] * ((get_index[i] - get_index[i - 1]) >> 1)+dp[i - 1][1] * ((get_index[i] - get_index[i - 1] - 1) >> 1);}return (dp[len - 1][0] + dp[len - 1][1]);}int main(){//freopen("input.txt", "r", stdin);Fib();int T;scanf("%d", &T);while (T--) {int64 n;int len = 0;scanf("%I64d", &n);for (int i = 86; i >= 1; --i) {if (F[i] <= n) {n -= F[i];get_index[len++] = i;}}if (n) { // 若无法将 N 拆分成不等的Fibonacci数之和,输出 0。//(这里不判断也可以AC,但是目前我无法给出“任何一个正整数都可以用不等的Fibonacci数列表示”的数学证明)printf("0\n");continue;}reverse(get_index, get_index + len);printf("%I64d\n", Solve(len));}return 0;}
0 0
- DP + math 之 Codeforces 126D - Fibonacci Sums
- codeforces 126D Fibonacci Sums 递推 DP
- Codeforces 126D Fibonacci Sums 求n由任意的Sum(fib)的方法数 dp
- CF(D. Fibonacci Sums)dp计数
- Codeforces Beta Round #93 (Div. 1 Only) D. Fibonacci Sums
- CodeForces 599D Spongebob and Squares(DP+math)
- codeforces 148D之概率DP
- codeforces 182D KMP+math
- 【DP】CodeForces 148D
- Codeforces 221D(dp)
- Codeforces 572D,DP
- codeforces 9D DP
- codeforces 519D dp
- Codeforces 358D【DP】
- codeforces 474D DP
- Codeforces 830D [DP]
- Codeforces 633D Fibonacci-ish(搜索)
- Codeforces 633D Fibonacci-ish 【暴力递归】
- UVA-11388
- SDIO
- 生活点滴 -- 做更好的自己,人生最不值得你去做的30件事
- 看文献心得--有舍有得
- C、Shell、Perl基于Tomcat开发CGI程序环境配置
- DP + math 之 Codeforces 126D - Fibonacci Sums
- Go如何发送广播包
- ZC301摄像头,OK6410的开发板,linux3.0.1,内核Oops的解决方法
- CloudTV Based on WebRTC(基于WebRTC的云电视)
- 4 Reasons why SharePoint is Dying 四个理由告诉你,为什么SharePoint即将死去
- hashtable详细介绍
- 机房收费系统系列一:运行时错误‘-2147217843(80040e4d)’;用户‘sa’登陆失败
- poj 2411 Mondriaan's Dream
- Android检测是否安装了指定应用