hdu 2049 考新郎 数学题

这题就是推递推关系,推了我两个小时,推出来以后觉得还是挺简单的。用一个二维数组存放结果,f(i, j)表示结果。除了当i = j时,f(i, i) = (i - 1) * [f(i - 1, i - 1) + f( i - 2, i - 2)]和j = 2时f(i,2) = f(i-1,2)+ i-1;之外,f(i, j)= f(i-1,j) +  f(i-1,j -1)*(j - 1) + f(i - 1, j - 2) * (i - j + 1);原理很简单,就是在一般情况下,f(i, j)只会由f(i - 1, j)、f(i - 1, j - 1)、f(i-1, j-2)三项组成,因为当最后一个新郎加进原有的新郎里的时候,只会有这三种情况。代码如下:

/*
* hdu2049/linux.c
* Created on: 2011-7-25
* Author : ben
*/
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include
<math.h>

void work();
int main() {
#ifndef ONLINE_JUDGE
freopen(
"data.in", "r", stdin);
#endif
work();
return 0;
}

unsigned
long long ans[30][30];

void init() {
int i, j, k;
memset(ans,
0, sizeof(ans));
ans[
2][2] = 1;
ans[
3][3] = 2;
ans[
3][2] = 3;
for (i = 4; i <= 20; i++) {
ans[i][i]
= (i - 1) * (ans[i - 1][i - 1] + ans[i - 2][i - 2]);
for (j = i - 1; j > 2; j--) {
ans[i][j]
= ans[i - 1][j];
ans[i][j]
+= ans[i - 1][j - 1] * (j - 1);
ans[i][j]
+= ans[i - 1][j - 2] * (i - j + 1);
}
ans[i][
2] = ans[i - 1][2] + i - 1;
}
}
void work() {
int T, i, j;
init();
scanf(
"%d", &T);
while (T--) {
scanf(
"%d %d", &i, &j);
printf(
"%I64u\n", ans[i][j]);
}
}
原文地址:https://www.cnblogs.com/moonbay/p/2116637.html