博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[BZOJ] 2660 [Beijing wc2012]最多的方案
阅读量:5914 次
发布时间:2019-06-19

本文共 1438 字,大约阅读时间需要 4 分钟。

Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 670  Solved: 387[Submit][Status][Discuss]Description       第二关和很出名的斐波那契数列有关,地球上的OIer都知道:F1=1, F2=2, Fi = Fi-1 + Fi-2,每一项都可以称为斐波那契数。现在给一个正整数N,它可以写成一些斐波那契数的和的形式。如果我们要求不同的方案中不能有相同的斐波那契数,那么对一个N最多可以写出多少种方案呢?Input       只有一个整数N。Output       一个方案数Sample Input       16Sample Output       4HINTHint:16=3+13=3+5+8=1+2+13=1+2+5+8对于30%的数据,n<=256对于100%的数据,n<=10^18Source

好题,很有意思。

第一反应是斐波那契数在1e18内不多,从大到小,贪心地选数。一个数能选的话,后面也一定能选,但不一定有第一处优,所以能选就选。

这样的构造是唯一的。

然后就是问题了, 对于这样的一个序列,任何一项a[i]都可以被a[i-1]和a[i-2]替代,需要求替代的方案数,也就是答案了。

这里卡住了,dp的威力就在此了。

f[i][0/1]表示a序列第i个数不替换/替换的方案数

f[i][1]=f[i-1][0]+f[i-1][1]
f[i][0]=f[i-1][0] * ((a[i]-a[i-1])/2)+f[i-1][1] * ((a[i]-a[i-1]-1)/2)

记得开longlong

#include
#include
#include
using namespace std;typedef long long ll;const int MAXN=1005;ll f[MAXN][2],fib[MAXN],n;ll a[MAXN],p;const int TOP=88;int main(){ fib[1]=1;fib[2]=2; for(int i=3;i<=TOP;i++) fib[i]=fib[i-1]+fib[i-2]; cin>>n; ll sav=n;// for(int i=TOP;i>=1;i--){ if(!sav) break; if(sav>=fib[i]) { a[++p]=i; sav-=fib[i]; } } if(sav) return cout<<0,0; sort(a+1,a+1+p); f[1][1]=1; f[1][0]=(a[1]-1)/2; for(int i=2;i<=p;i++){ f[i][1]=f[i-1][0]+f[i-1][1]; f[i][0]=f[i-1][0]*((a[i]-a[i-1])/2)+f[i-1][1]*((a[i]-a[i-1]-1)/2); } cout<

转载于:https://www.cnblogs.com/ghostcai/p/9247409.html

你可能感兴趣的文章
四则运算
查看>>
Qt5 for Android: incompatible ABI
查看>>
zookeeper学习
查看>>
class类名的管理
查看>>
LeetCode:Rectangle Area
查看>>
文本查询
查看>>
查看帐号授权信息
查看>>
小程序(四):模板
查看>>
【转】Java - printf
查看>>
jquery获取元素到屏幕底的可视距离
查看>>
ENDNOTE使用方法(转发)
查看>>
计算机数制和运算的一点总结.
查看>>
UML系列 (五) 为什么要用UML建模之建模的重要性
查看>>
框架是什么,框架有什么用(转)
查看>>
集成测试
查看>>
c3p0连接池配置
查看>>
对于I/O流中解压中遇到的问题
查看>>
问答项目---用户注册的那些事儿(JS验证)
查看>>
Android进阶篇-百度地图获取地理信息
查看>>
返回前一页并刷新页面方法
查看>>