Posted on 2010-08-06 16:00
MiYu 閱讀(720)
評論(0) 編輯 收藏 引用 所屬分類:
ACM ( 數論 ) 、
ACM ( 組合 )
MiYu原創, 轉帖請注明 : 轉載自 ______________白白の屋
題目地址:
http://acm.hdu.edu.cn/showproblem.php?pid=2068
題目描述:
Problem Description
今年暑假杭電ACM集訓隊第一次組成女生隊,其中有一隊叫RPG,但做為集訓隊成員之一的野駱駝竟然不知道RPG三個人具體是誰誰。RPG給他機會讓他猜猜,第一次猜:R是公主,P是草兒,G是月野兔;第二次猜:R是草兒,P是月野兔,G是公主;第三次猜:R是草兒,P是公主,G是月野兔;
可憐的野駱駝第六次終于把RPG分清楚了。由于RPG的帶動,做ACM的女生越來越多,我們的野駱駝想都知道她們,可現在有N多人,他要猜的次數可就多了,為了不為難野駱駝,女生們只要求他答對一半或以上就算過關,請問有多少組答案能使他順利過關。
Input
輸入的數據里有多個case,每個case包括一個n,代表有幾個女生,(n<=25), n = 0輸入結束。
Sample Input
1
2
0
Sample Output
1
1
很明顯的 錯排 + 排列組合 的題目. 更多錯排資料請點擊 --> << 錯排公式 >>
要猜對一半或一半以上, 那么就是從給出的 n 個人中 取出 小于或等于 n / 2 的人進行錯排 ,
因為題目問的是順利通關的所有解, 所以最后需要累加 0 -> n / 2 的錯排方法.
錯排公式 :
F ( n ) = ( n - 1 ) * ( F(n-1) + F ( n - 2 ) ) 代碼如下 :
//MiYu原創, 轉帖請注明 : 轉載自 ______________白白の屋
#include <stdio.h>
typedef long long int64;
int64 Com ( int n, int m ) // 取 Cn m 的 組合數
{
if ( m == 0 )
{
return 1;
}
int64 up = 1,down = 1;
for ( int i = 0; i < m; ++ i )
{
up *= n - i;
down *= i + 1;
}
return up / down;
}
int64 F[14] = { 0, 0, 1, 2 };
void setNum ()
{
for ( int i = 4; i < 14; ++ i )
{
F[i] = ( i - 1 ) * ( F[ i - 1 ] + F[ i - 2 ] );
}
}
int main ()
{
int N;
int64 sum;
setNum ();
while ( scanf("%d", &N), N )
{
sum = 1;
for ( int i = N / 2; i >= 0; -- i )
{
sum += Com ( N , i ) * F[i]; // 從N中取i 個人 的錯排數
}
printf("%I64d\n", sum );
}
}