hdu_problem_2049_不容易系列之(4)——考新郎

N个人里面有M个人选错了,可以看成从N个人里面选M个人(组合数公式C(N,M),可以参考杨辉三角)然后M个人对应的位置都错了(可以参考problem_2048)

/*
*
*Problem Description
*国庆期间,省城HZ刚刚举行了一场盛大的集体婚礼,为了使婚礼进行的丰富一些,司仪临时想出了有一个有意思的节目,叫做"考新郎",具体的操作是这样的:
*
*
*首先,给每位新娘打扮得几乎一模一样,并盖上大大的红盖头随机坐成一排;
*然后,让各位新郎寻找自己的新娘.每人只准找一个,并且不允许多人找一个.
*最后,揭开盖头,如果找错了对象就要当众跪搓衣板...
*
*看来做新郎也不是容易的事情...
*
*假设一共有N对新婚夫妇,其中有M个新郎找错了新娘,求发生这种情况一共有多少种可能.
*
*
*Input
*输入数据的第一行是一个整数C,表示测试实例的个数,然后是C行数据,每行包含两个整数N和M(1<M<=N<=20)。
*
*
*Output
*对于每个测试实例,请输出一共有多少种发生这种情况的可能,每个实例的输出占一行。
*
*
*Sample Input
*2
*2 2
*3 2
*
*
*Sample Output
*1
*3
*
*
*Author
*lcy
*
*
*Source
*递推求解专题练习(For Beginner)
*
*
*Recommend
*lcy
*
*/
#include<iostream>
#define MAX_NUM 20
using namespace std;
long long num_zuhe[MAX_NUM] = { 1,1,2 };// m个数字对应的数互不相同的情况
long long triangle_zuhe[MAX_NUM][MAX_NUM];// 组合数
// 打表
void func_1() {
 for (int i = 3; i < MAX_NUM; i++) {
  num_zuhe[i] = i * (num_zuhe[i - 1] + num_zuhe[i - 2]);
 }
}
void func_2() {
 for (int i = 0; i < MAX_NUM; i++) {
  triangle_zuhe[i][i] = 1;
  triangle_zuhe[i][0] = 1;
 }
 for (int i = 0; i < MAX_NUM; i++) {
  for (int j = 1; j <= i - 1; j++) {
   triangle_zuhe[i][j] = triangle_zuhe[i - 1][j - 1] + triangle_zuhe[i - 1][j];
  }
 }
}
int main() {
 int C, n, m;
 cin >> C;
 func_1();
 func_2();
 for (int i = 0; i < C; i++) {
  cin >> n >> m;
  if (m == 1) { cout << 0 << endl; continue; }
  cout << triangle_zuhe[n][m] * num_zuhe[m - 1] << endl;
 }
 system("pause");
 return 0;
}

猜你喜欢

转载自blog.csdn.net/CoderMaximum/article/details/86348576