RPG的错排
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 17479 Accepted Submission(s): 7020
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
Author
Rabbit
Source
RPG专场练习赛
Recommend
lcy
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2068
简述:给出一个n表示n个女生,野骆驼至少要猜对(n+1)/2或以上个女生才能过关,问他能过关的答案有多少组。
分析:至少要有(n+1 )/ 2 或以上个女生被猜对,即至多有n / 2个女生错排【即0 ~ n / 2都有可能】。写出错排函数f(n)=(n-1)*(f(n-1)+f(n-2)),【用数组来写】。其中,这0 ~ n / 2个女生中究竟是n个女生中的哪些,要用到排列组合。【c(n, m)】,把 c(n, m)*f(n) 在(0 ~ n / 2)范围内相加就是答案。
说明:排列组合函数跟错排函数要用long long类型,排列组合函数不可用递归,不可用直接相乘再累加,会溢出。要写出它n!跟(n-m)!相约后的代码。
AC代码如下:
#include <iostream>
#include <cstring>
using namespace std;
long long f(int n)
{
long long a[26] = { 0 };
int i;
a[0] = 1;
a[1] = 0;
a[2] = 1;
for (i = 3; i <= 25; i++)
{
a[i] = (i - 1) * (a[i - 1] + a[i - 2]);
}
return a[n];
}
long long c(int n, int m)//阶乘
{
long long t=1;
int i;
for (i = 1; i <= m; i++)
{
t = t * (n - i + 1) / i;
}
return t;
}
int main()
{
long long t=0;
int n, g, i;
while (cin >> n && n != 0)
{
t = 0;
g = n / 2;
for (i = 0; i <= g; i++)
{
t += (c(n, i) * f(i));
}
cout << t << endl;
}
}