先引入一道题:
前言:在地球上的某一个角落,生活着一群神奇的人。他们拥有神圣的力量,能够穿梭、制造时空,创造虫洞、奇点等。他们称自己为“时空跳跃者”。
背景:作为时空跳跃者高级祭司的飞翔,为了追寻更强大的力量,背叛了时空跳跃者。于是,时空跳跃者的圣殿战士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.