bzoj2660
dp
看了挺长时间的,这篇写的很好:http://97littleleaf11.xyz/oi/bzoj-2660/
我们先把n按照斐波那契数列贪心分解,然后发现可以把现在组合的斐波那契数分解成两个较小的,具体看博客,然后就是dp转移,上面的博客图画的很清楚了,转移就很方便
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; const int N = 110; int top; long long n; long long f[N], dp[N][2], st[N]; int main() { cin >> n; f[1] = 1; f[2] = 2; for(int i = 3; i <= 88; ++i) f[i] = f[i - 1] + f[i - 2]; for(int i = 88; i; --i) if(n - f[i] >= 0) { n -= f[i]; st[++top] = i; } reverse(st + 1, st + top + 1); dp[1][1] = 1; dp[1][0] = (st[1] - 1) >> 1; for(int i = 2; i <= top; ++i) { dp[i][1] = dp[i - 1][0] + dp[i - 1][1]; dp[i][0] = dp[i - 1][0] * ((st[i] - st[i - 1]) >> 1) + dp[i - 1][1] * ((st[i] - st[i - 1] - 1) >> 1); } cout << dp[top][0] + dp[top][1]; return 0; }