H - RPG的错排
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
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输入结束。
Output
1 1
Sample Input
1 2 0
Sample Output
1 1
________________
考察错排
学习递推思想,要考虑对于第n个数放到第k个位置的时候,
第K个数放在第n位和不是第n位两个情况。
通过百度百科和其他博客学习了一下递推的正确推导方式,进一步加深了理解,大概能明白递推应该从什么样的角度思考了 。
以往总是把递推想太复杂了,光想推导着数学上的通项公式之类的……启示如果正确理解递推思想,递推起来不是很难。
代码如下 :
#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std ;
long long int cuopai[30];
void init_cuopai( int n )
{
cuopai[0] = 1 ; // 这是特殊情况,下面会提到.
cuopai[1] = 0; // 这里一开始被卡了一下 ,以为是1的.
cuopai[2] =1;
for( int i = 3 ; i <= n ; i++)
cuopai[i]= (i-1)*(cuopai[i-1] + cuopai[i-2] ) ;
return ;
}
long long int zuhe( int m , int n ) // 从m个数取n 组合
{
long long int ans = 1 ;
for( int i = 1 ; i <= n ; i++)
ans= ans*( m - i + 1 ) / i ;
return ans ;
}
int main()
{
int n ;
init_cuopai(25);
while( cin >> n )
{ if( n == 0 ) break ;
long long int ans=0;
for( int i = 0 ; i <= n/2 ; i++)
{
ans+= zuhe(n,i)*cuopai[i] ;
//他让求正确的答案有多少组,那么也就是0个错排
//1个错排,一直到n/2都错排的数量就好了,需要考虑的是,全部正确也是答案,所以特判
// 0个错排是1
}
cout<< ans << endl ;
}
return 0 ;
}
原文:http://www.cnblogs.com/xiekeyi98/p/6280298.html