查看题目 Show Problem
题目:[AHOI1997]彩旗飘飘
问题编号:371
题目描述
有n面红旗和n面黄旗从东到西插成一排。如果相邻的两面旗帜的颜色不同,则称为颜色发生一次改变。
任务:计算这2n面旗帜的颜色改变m次的插法共有多少种?
示例:
旗帜的颜色为“红黄红红黄黄黄”称为颜色改变了3次的插法。
在n=4,m=1时仅有两种插法:“红红红红黄黄黄黄”和“黄黄黄黄红红红红”,对应的输出为“2”。
输入格式
输入:从键盘上依闪输入自然数n和m。(n<15)
输出格式
输出:把插法总数在屏幕上显示输出。
样例输入
4 1
样例输出
2
f:array[0..15(红旗数),0..15(黄旗数),0..30(改变数),0..1(最后是黄旗[0]还是红旗[1])]of longint;
f[i,j,k,0]=f[i-1,j,k,1]+f[i-2,j,k,1]+f[i-3,j,k,1]+......+f[1,j,k,1];
例如
f[4,4,4,1]=
红红黄红红黄黄红+红黄红红红黄黄红+。。。。。。+@@@@@@@(f[3,4,4,0])+红
红红黄红红黄红红+。。。。。。+@@@@@@(f[2,4,4,1]=)红红+
。。。。。。+
@@@@红红红红
代码
program
Project1;
const max = 15 ;
var f: array [ 0 .. 15 , 0 .. 15 , 0 .. 30 , 0 .. 1 ] of longint;
n,m,i,j,k,l:longint;
begin
for i: = 1 to max do
for j: = 1 to max do
begin f[i,j, 1 , 0 ]: = 1 ;f[i,j, 1 , 1 ]: = 1 end ;
for k: = 2 to max * 2 do
for i: = 1 to max do
for j: = 1 to max do
begin
for l: = 1 to i do
inc(f[i,j,k, 0 ],f[i - l,j,k - 1 , 1 ]);
for l: = 1 to j do
inc(f[i,j,k, 1 ],f[i,j - l,k - 1 , 0 ]);
end ;
readln(n,m);
writeln(f[n,n,m, 0 ] + f[n,n,m, 1 ]);
end .
const max = 15 ;
var f: array [ 0 .. 15 , 0 .. 15 , 0 .. 30 , 0 .. 1 ] of longint;
n,m,i,j,k,l:longint;
begin
for i: = 1 to max do
for j: = 1 to max do
begin f[i,j, 1 , 0 ]: = 1 ;f[i,j, 1 , 1 ]: = 1 end ;
for k: = 2 to max * 2 do
for i: = 1 to max do
for j: = 1 to max do
begin
for l: = 1 to i do
inc(f[i,j,k, 0 ],f[i - l,j,k - 1 , 1 ]);
for l: = 1 to j do
inc(f[i,j,k, 1 ],f[i,j - l,k - 1 , 0 ]);
end ;
readln(n,m);
writeln(f[n,n,m, 0 ] + f[n,n,m, 1 ]);
end .