bzoj 2660: [Beijing wc2012]最多的方案 递推

本文探讨了利用动态规划解决斐波那契数列相关问题的方法,并给出了具体的AC代码实现。通过分析第k个斐波那契数的构成情况,设计了一种高效的求解方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       本来想打个lct的。。。发现太浪了时间不够用了。

       于是打算随手水一发。

       结果发现自己这种傻逼题都不会写了。。。。。。。。满满的滚粗既视感QAQ。。

       考虑第k个斐波那契数的方案f[k],显然它可以由自己构成;如果选第k-1个斐波那契数,那么显然方案就是f[k-2];否则只有一种方案。

       然后dp令f[k][0]表示不选第k个斐波那契数的方案,f[k][1]表示选,弄出n可以由哪些表示就好了。

AC代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define N 105
using namespace std;

ll n,f[N],dp[N][2]; int q[N];
int main(){
	scanf("%lld",&n); int i;
	f[1]=1; f[2]=2;
	for (i=3; f[i-1]+f[i-2]<=n; i++) f[i]=f[i-1]+f[i-2];
	int tp=0;
	for (i--; i && n; i--) if (n>=f[i]){ q[++tp]=i; n-=f[i]; }
	dp[tp][1]=1; dp[tp][0]=(q[tp]-1)>>1;
	for (i=tp-1; i; i--){
		dp[i][1]=dp[i+1][0]+dp[i+1][1];
		dp[i][0]=dp[i+1][0]*((q[i]-q[i+1])>>1)+dp[i+1][1]*((q[i]-q[i+1]-1)>>1);
	}
	printf("%lld\n",dp[1][0]+dp[1][1]);
	return 0;
}

by lych

2016.5.4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值