3150 Pibonacci数 - Wikioi
题目描述 Description
你可能听说过的Fibonacci数和圆周率Pi。
如果你让这两个概念合并,一个新的深奥的概念应运而生:Pibonacci数。
这些数可以被定义为对于x>=0:
如果0<=x<4,则P(x) = 1
如果4<=x,则P(x) = P(x - 1) + P(x - pi)
其中Pi = 3.1415926535897...在这个问题中,你被要求计算对于一个给定的非负整数x对应P(x)的值。
输入描述 Input Description
一个非负整数x。
输出描述 Output Description
一个正整数P(x)。
样例输入 Sample Input
11
样例输出 Sample Output
20
数据范围及提示 Data Size & Hint
数据范围 x<=30000
来源 ICPC 2001 F
好题啊
转化题意,给你一个数,你可以一次减去1,或者减去pi,求你有多少种方法把它减到<4(如果它本来就小于4,方案就是1种)
想法1
枚举1的个数算出pi的个数,这是pi结尾的,算组合数
枚举pi的个数算出1的个数这是1结尾的,算组合数
然后加起来
眼瞎,以为只有3000,高兴地交上去,RE了,我靠竟然有30000,怎么办呢
问了问VFleaking,他想了想,帮我找出了一个有巨大优化空间的地方
我求组合数是暴力求的,其实枚举的时候组合数的n,m都是比较接近的,所以记一个lastn和一个lastm每次只要乘几个除几个就行了
然后优化到了10000左右可以过,又卡住了
FVleaking找到了差不多的题http://acm.hit.edu.cn/hoj/problem/view?id=1385
范围是3000,多组数据,我就交了,AC了,于是我的信心倍增,但是还是不知道怎么过30000
然后下了一个C++AC代码(当时也只有C和C++的)
看了以后果然是常数比我好
直接枚举pi的个数为n
然后给剩下的空间加上一个pi,算出这个空间可以容下多少个1,个数为m
可以想象,加上一个pi,pi的个数还是原来枚举的那么多(因为这个空间加上这些pi和1肯定还没满)
所以讨论1摆放情况,因为有可能1结尾,但是超出范围,根本不需要这个1,但是没关系这个方案只计算了一次也只会计算这一次,所以方案数就是C(n+m,n)
然后加上前面那个优化,就可以AC了..........
const
h=;
type
aa=array[..]of int64;
var
a,b:aa;
n:longint; procedure cheng(x:longint);
var
i:longint;
begin
for i:= to b[] do
b[i]:=b[i]*x;
for i:= to b[] do
begin
inc(b[i+],b[i]div h);
b[i]:=b[i]mod h;
end;
i:=b[]+;
while b[i]> do
begin
inc(b[]);
b[i+]:=b[i]div h;
b[i]:=b[i]mod h;
inc(i);
end;
end; procedure jia;
var
i:longint;
begin
for i:= to b[] do
inc(a[i],b[i]);
if b[]>a[] then a[]:=b[];
for i:= to a[] do
begin
inc(a[i+],a[i]div h);
a[i]:=a[i]mod h;
end;
i:=a[]+;
while a[i]> do
begin
inc(a[]);
inc(a[i+],a[i]div h);
a[i]:=a[i]mod h;
inc(i);
end;
end; procedure chu(x:longint);
var
i:longint;
begin
for i:=b[] downto do
begin
inc(b[i-],(b[i]mod x)*h);
b[i]:=b[i]div x;
end;
b[]:=b[]div x;
while (b[b[]]=)and(b[]>) do
dec(b[]);
end; procedure print;
var
i:longint;
k:int64;
begin
write(a[a[]]);
for i:=a[]- downto do
begin
k:=h div ;
while k> do
begin
if a[i]<k then write();
k:=k div ;
end;
write(a[i]);
end;
end; procedure main;
var
i,j,k,last:longint;
begin
read(n);
if n< then
begin
write();
halt;
end;
dec(n,);
a[]:=;
a[]:=;
i:=;
b[]:=;
b[]:=;
i:=;
j:=trunc(n+pi);
while i<=trunc((n+pi)/pi) do
begin
last:=j;
j:=trunc(n+pi-i*pi);
for k:=last- downto j+ do
begin
cheng(k+);
chu(i+k);
end;
cheng(j+);
chu(i);
inc(i);
jia;
end;
print;
end; begin
main;
end.
3150 Pibonacci数 - Wikioi的更多相关文章
- 【wikioi】1227 方格取数 2(费用流)
http://www.wikioi.com/problem/1227 裸题,拆点,容量为1,费用为点权的负数(代表只能取一次).再在拆好的两个点连边,容量为oo,费用为0.(代表能取0) 然后向右和下 ...
- 【wikioi】1907 方格取数3(最大流+最大权闭合子图)
http://www.wikioi.com/problem/1907/ 这题我一开始想到的是状压,看到n<=30果断放弃. 然后也想到了黑白染色,然后脑残了,没想到怎么连边. 很简单的一题 黑白 ...
- 【wikioi】1553 互斥的数(hash+set)
http://wikioi.com/problem/1553/ 一开始我也知道用set来判a[i]/p是否在集合中,在的话就直接删掉. 但是我没有想到要排序,也没有想到当存在a,b使得a/p==b时到 ...
- [wikioi]数的划分
http://wikioi.com/problem/1039/ 划分型DP.最终的思路是,F[i][j]表示i分成j份,如果分出来的有1,那么去掉1,就是F[i-1][j-1]:如果没有1,那就都减1 ...
- wikioi 1166 矩阵取数游戏
这题做了至少5个小时= =,虽然思路一开始就确定了,但是因为一些错误,比如dp公式里的+打成*,状态未初始化等原因调了好久(>_<) 最后还是参照着别人的解题报告找到错误. 大数模板直接拿 ...
- 【wikioi】1040 统计单词个数
题目链接 算法:划分型DP PS:被卡过3天.日期:2013-10-10 ~ 2013-10-12 18:52:48 这题是我提交了13次AC= =汗= = 题目描述: 给出一个长度不超过200的由小 ...
- 【wikioi】1904 最小路径覆盖问题(最大流+坑人的题+最小路径覆盖)
http://wikioi.com/problem/1904/ 这题没看数据的话是一个大坑(我已报告官方修复了),答案只要求数量,不用打印路径...orz 最小路径覆盖=n-最大匹配,这个我在说二分图 ...
- 【wikioi】2216 行星序列(线段树)
http://wikioi.com/problem/2216/ 这题太让我感动了QAQ,让我找到了我一直以来写线段树的错误!!!! 就是,pushdown一定要放在最前面!要不然顺序会错.也就是说,当 ...
- 【wikioi】1403 新三国争霸(dp+kruskal)
http://wikioi.com/problem/1403/ 一开始的确感觉和bzoj1003很像,不同的是这里还要求联通,求最小的边. 我们可以想到用最小生成树(为嘛我自己想不到呢..) 我们可以 ...
随机推荐
- javascript事件学习笔记
事件冒泡 并不是所有的事件都支持事件冒泡,比如submit ,focus,blur不支持事件冒泡,mouseover,mouseout虽然支持冒泡,但是一般不用,因为需要经常计算元素的位置,消耗比较大 ...
- sql 截取两个字符串之间的字符
select SUBSTRING(templatepath,CHARINDEX('/',templatepath)+1,CHARINDEX('.', templatepath)-CHARINDEX(' ...
- Oracle表空间操作
-- 查看表空间 SELECT tablespace_name, file_id, file_name, ), )||'M' total_space FROM dba_data_files ORDER ...
- Reset / Validate Buffer
AL12
- 【转】Session与Cookie的比较
最近发现写博客也是提高学习效率的有效途径之一.好记性不如烂笔头,归纳总结时,你会发现总有一些东西你认为很熟了,它却在细微处讽刺你的错误.我学习COOKIE与SESSION时,几乎把社区所有相关的帖子都 ...
- margin折叠
什么是margin折叠:当两个或更多个垂直边距相遇时,它们将形成一个外边距.这个外边距的高度等于两个发生叠加的外边距的高度中的较大者. 注意: (1 ...
- 压力测试工具siege的用法
Siege是linux下的一个web系统的压力测试工具,支持多链接,支持get和post请求,可以对web系统进行多并发下持续请求的压力测试. 安装 Siege 01 02 03 04 #wget h ...
- 一个例子说明如何在DataSnap中使用FireDAC
一.FireDAC调用DataSnap远程方法查询数据示例 1.服务端使用FDQUERY查询数据并返回TDATASET: function TServerMethods1.GetData(var sq ...
- Spark Streaming揭秘 Day27 Job产生机制
Spark Streaming揭秘 Day27 Job产生机制 今天主要讨论一个问题,就是除了DStream action以外,还有什么地方可以产生Job,这会有助于了解Spark Streaming ...
- Spark Streaming揭秘 Day26 JobGenerator源码图解
Spark Streaming揭秘 Day26 JobGenerator源码图解 今天主要解析一下JobGenerator,它相当于一个转换器,和机器学习的pipeline比较类似,因为最终运行在Sp ...