卡特兰数(Catalan number)

先引入一道题:

前言:在地球上的某一个角落,生活着一群神奇的人。他们拥有神圣的力量,能够穿梭、制造时空,创造虫洞、奇点等。他们称自己为“时空跳跃者”。

背景:作为时空跳跃者高级祭司的飞翔,为了追寻更强大的力量,背叛了时空跳跃者。于是,时空跳跃者的圣殿战士suntian被命令去追捕飞翔……

描述:在出发前,suntian特意去了圣殿收集能量。圣殿中央有一个n芒星,这个n芒星的每一个顶点都有不同的文字,每一个顶点都被称为一个量点,每两个量点可以连成一条量点线。为了收集到能量,suntian必须站在这个n芒星阵中,用手指画出相应的咒文。这个咒文是这样产生的:用n-3条量点线将n芒星划分为n-2个互相没有重叠的三角形。suntian每成功完成一个咒文,就可以获得1Tas(时空跳跃者的能量单位)。那么,suntian最多能获得多少Tas的能量呢?(一种咒文只能用一次)

 

输入:共一行,为n,5<=n<=100,n∈N

输出:共一行,为总能量W。

样例输入:5

样例输出:5Tas


本人saca,知道本题数学相关,但是不会做,后来才知道这是卡特兰数。


详细请见百科或书面资料(如:《全国青少年信息学奥林匹克联赛培训教材(中学高级本)》P19)!!!


本人给出一个递推公式:


就这样。。。


下附代码:

program catalan (input,output)
type structure=record
  len:longint;
  w:array[0..550]of longint;
end;
var num:array[0..110]of structure;
var n,i,k,len:longint;
    temp:array[0..550]of longint;

procedure mul(j1,j2:longint);
var i,j:longint;
begin
for i:=1 to num[j1].len do
 for j:=1 to num[j2].len do
  temp[i+j-1]:=temp[i+j-1]+(num[j1].w[i]*num[j2].w[j]);
if num[j1].len>num[j2].len then
 len:=num[j1].len
else
 len:=num[j2].len;
for i:=1 to len do
 if temp[i]>=10 then
  begin
    temp[i+1]:=temp[i+1]+(temp[i] div 10);
    temp[i]:=temp[i] mod 10;
  end;
len:=num[j1].len+num[j2].len+10;
while temp[len]=0 do
 dec(len);
end;

procedure add(ord:longint);
var i:longint;
begin
for i:=1 to len do
 num[ord].w[i]:=num[ord].w[i]+temp[i];
for i:=1 to len do
 if num[ord].w[i]>=10 then
  begin
    num[ord].w[i+1]:=num[ord].w[i+1]+(num[ord].w[i] div 10);
    num[ord].w[i]:=num[ord].w[i] mod 10;
  end;
if num[ord].w[len+1]<>0 then
 inc(len);
num[ord].len:=len;
fillchar(temp,sizeof(temp),0);
end;

procedure print(c:longint);
var i:longint;
begin
for i:=num[c].len downto 1 do
 write(num[c].w[i]);
write('Tas');
end;

begin
assign(input,'energy.in');
assign(output,'energy.out');
reset(input);
rewrite(output);
readln(n);
num[2].len:=1;
num[3].len:=1;
num[2].w[1]:=1;
num[3].w[1]:=1;
for i:=4 to n do
begin
 for k:=2 to i-1 do
  begin
    mul(k,i-k+1);
    add(i);
  end;
end;
print(n);
close(input);
close(output);
end.




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值