查看文章 |
放牙刷 (put.pas/c/cpp)【问题描述】 众所周知,黄黄同学早晨起来是要刷牙的。 黄黄同学有N支牙刷,又有N个牙刷套,开始的时候,一支牙刷对应放在一个牙刷套中。可是有一天,黄黄同学把所有牙刷套里的牙刷都拿出来,玩了一会儿,他又要把所有的牙刷都放回去。可是,他忽然一想,我可不可以使得没有任何一支牙刷放回它原来的牙刷套里面呢? 黄黄同学努力试了很久,却一直没有成功过一次。于是他断定这个要求是无法达成的,你怎么认为的呢? 【输入文件】 输入文件put.in只包括一个整数N,表示牙刷和牙刷套的总数。 【输出文件】 输出文件put.out,如果存在满足要求的方法,输出放法方案总数L。因为方案总数可能比较大,所以你可以将答案Mod 1206后再输出。如果不存在满足要求的方法,则输出"No Solution!” 【样例输入】 3 【样例输出】 2 【数据范围】 对于40%的数据,保证N≤9 对于100%的数据,保证N≤100000 【时限】 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; |