bzoj2660: [Beijing wc2012]最多的方案

题目链接

bzoj2660: [Beijing wc2012]最多的方案

题解

对于一个数的斐波那契数列分解,他的最少项分解是唯一的
我们在拆分成的相临两项之间分解后者,这样形成的方案是最优且不重的
我们可以把它的分解某一项拆分
设dp[i][1/0]表示 对于最少拆分成的第i项斐波那切数拆不拆
在上一项j与这一项i的斐波那契数之间拆i项共有(i-j)/2种拆分方法,
转移方程就有了

代码

/*
对于一个数的斐波那契数列分解,他的最少项分解是唯一的
我们在拆分成的相临两项之间分解后者,这样形成的方案是最优且不重的 
我们可以把它的分解某一项拆分
设dp[i][1/0]表示 对于最少拆分成的第i项斐波那切数拆不拆
在上一项j与这一项i的斐波那契数之间拆i项共有(i-j)/2种拆分方法,  
转移方程就有了 
*/
#include<vector> 
#include<cstdio> 
#include<cstring> 
#include<algorithm> 
#define LL long long
inline int read() { 
    int x = 0,f = 1;char c = getchar(); 
    while(c < '0'||c > '9')c = getchar(); 
    while(c <= '9' &&c >= '0')x = x * 10 + c - '0',c = getchar(); 
    return x * f; 
} 
LL f[107]; 
int a[107],tmp[107]; 
LL dp[107][2]; 
int main() {
    f[1] = 1;f[2] = 2; 
    LL n;
    scanf("%lld",&n); 
    int num = 3; for(num = 3;;++ num) {f[num] = f[num - 1] + f[num - 2]; if(f[num] > n) break;} 
    int sum = 0; 
    for(int i = num;i >= 1;-- i) if(n >= f[i]) n -= f[i],tmp[++ sum] = i; 
    for(int cnt = 0,i = sum;i >= 1;-- i) a[++ cnt] = tmp[i]; 
    dp[1][1] = 1; 
    dp[1][0] = a[1] - 1 >> 1; 
    for(int i = 2;i <= sum;++ i) { 
        dp[i][1] = dp[i - 1][1] + dp[i - 1][0];  
        dp[i][0] = dp[i - 1][1] * (a[i] - a[i - 1] - 1 >> 1) + dp[i - 1][0] * (a[i] - a[i - 1] >> 1);  
    }  
    printf("%lld\n",dp[sum][1] + dp[sum][0]);  
    return 0;  
}  

转载于:https://www.cnblogs.com/sssy/p/9270178.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值