百度空间 | 百度首页 
 
查看文章
 
放牙刷 (put.pas/c/cpp)(错位排序)(错位排列)
2008年11月11日 星期二 下午 02:31

放牙刷 (put.pas/c/cpp)

【问题描述】

    众所周知,黄黄同学早晨起来是要刷牙的。

    黄黄同学有N支牙刷,又有N个牙刷套,开始的时候,一支牙刷对应放在一个牙刷套中。可是有一天,黄黄同学把所有牙刷套里的牙刷都拿出来,玩了一会儿,他又要把所有的牙刷都放回去。可是,他忽然一想,我可不可以使得没有任何一支牙刷放回它原来的牙刷套里面呢?

    黄黄同学努力试了很久,却一直没有成功过一次。于是他断定这个要求是无法达成的,你怎么认为的呢?

【输入文件】

    输入文件put.in只包括一个整数N,表示牙刷和牙刷套的总数。

【输出文件】

    输出文件put.out,如果存在满足要求的方法,输出放法方案总数L。因为方案总数可能比较大,所以你可以将答案Mod 1206后再输出。如果不存在满足要求的方法,则输出"No Solution!”

【样例输入】

    3

【样例输出】

    2

【数据范围】

    对于40%的数据,保证N9

    对于100%的数据,保证N100000

    【时限】

    ls

很容易看出它就是错位排列,用通项公式明显不适用,应使用递推式

F[I]=(I-1)*(F[I-1]+F[I-2])

证明:*  * *  * *  *....

   1 2 3 4 5 6....

假设现在I=6,第6位上有5种选择(I-1),比如在第6位上放的是3,如果第3位上又被6占据,那么剩下的4位自行错位排列有F[4]种方案(F[I-2]),可以把这种情况视为3\6原先各在其位,其余4位错位,而后3/6互换

如果如果没有出现3\6相互占据的情况,说明3不在第3位上,3\6互换前,前5位已错位排序讫,那么就有F[5]种情况,互换后依然满足错位,方案数也是F[I-1]

所以F[I]=(I-1)*(F[I-1]+F[I-2])

边界F[2]=1 F[3]=2

N=0或N=1无解

program fgdfdfd;
var n,i,j:longint;
    f:array[1..100000]of longint;
begin
assign(input,'put.in');assign(output,'put.out') ;
reset(input); rewrite(output);
fillchar(f,sizeof(f),0);
f[2]:=1 ; f[3]:=2;
readln(n);
if n in [0..1] then writeln('No Solution!')
else
begin
for i:=4 to n do
f[i]:=((i-1)*(f[i-1] +f[i-2] )) mod 1206;
writeln(f[n]) ;
end;
close(input); close(output);
end.


类别:题解 | 浏览() | 评论 (1)
 
最近读者:
 
网友评论:
1
2009年03月09日 星期一 下午 06:22 | 回复
真厉害!!!
 
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu