题目描述
现在有位男生和位女生,要从中挑选位排成一排,要求每名女生的前后至少有另一名女生。请你求出排列的方案总数。
输入格式
一个整数。
输出格式
一个整数,表示方案总数。
样例输入
4
样例输出
7
样例解释
在种方案中,有女女女女、女女女男、男女女女、女女男男、男女女男、男男女女、男男男男,共种可行方案。
数据规模与约定
对于的数据,。
解题
首先要明白,为什么每名女生的前后至少有另一名女生?
显然是我想多了,开始正经解题。
这是一道求方案总数的题,看样子可以用递推。为了方便,我们用B表示男生,用G表示女生。
设:队列由男生和女生共位组成,构造函数来表示合法方案数。
接下来就是墨迹。不,是严密的推理。
按照递推的思想,一种合法方案是怎样得到的?在一种方案的末尾加一个B或G,使之构成一种合法方案。注意,我没有说一种合法方案,因为一种不合法方案末尾加一个B或G,也有可能构成一种合法方案。推导如下:
如果一种不合法方案的末尾是B,那么再加一个B或G仍然不合法。如果一种不合法方案的末尾是G,又分几种情况:
情况一:如果倒数第二个是G,那么再加一个B或G仍然不合法。
情况二:如果倒数第二个是B,且倒数第二个的前面还有其他不合法处,那么再加一个B或G仍然不合法。
情况三:如果倒数第二个是B,且倒数第二个的前面没有不合法处,说明问题出在最后这两个元素上。此时,如果在末尾加一个G,可以转不合法为合法。
那么共有多少种情况三呢?我们说倒数第二个的前面没有不合法处,换句话说,去掉最后这两个元素,就是一种合法方案。方案总数为。
再回到最开始的问题。一种合法方案的末尾加一个B或G,当然也有可能构成一种合法方案。我们事先假设:一种合法方案的末尾加一个B或G,必构成一种合法方案。按此,方案总数为。推导如下:
如果一种合法方案的末尾是G,那么再加一个B或G它还是合法。如果一种合法方案的末尾是B,则加B合法,加G不合法。
那么以B结尾的合法方案是怎样得到的?根据刚才的证明,在末尾加B这一操作不能实现转不合法为合法。换句话说,去掉末尾这个B,前面部分还是合法的。方案总数为。但注意这里不是加,是在事先假设的基础上减掉。
综上所述得关系:
要想顺着关系式推,还差一步,那就是算出和还有。
如果只有一个,那么一定是B。故。
如果有两个,那么BB、BG(舍去)、GB(舍去)、GG。故。
如果有三个,那么BBB、BBG(舍去)、BGB(舍去)、BGG、GBB(舍去)、GBG(舍去)、GGB、GGG。故。
分析完毕,写代码只需一瞬间。
#include <cstdio>
long long n, f[101];
int main() {
scanf("%lld", &n);
f[1] = 1;
f[2] = 2;
f[3] = 4;
for (int i = 4; i <= n; i++)
f[i] = 2 * f[i - 1] - f[i - 2] + f[i - 3];
printf("%lld\n", f[n]);
}
结果:正确(用时1毫秒)
感谢大家的支持,我是汤圆,我们下期再见!