吉比特2020春招笔试题第二题——排列组合问题

吉比特2020春招题目(3.14),排列组合的题目,比较有意思。
题目这么讲:输入一个n(1<=n<=1e9),输出满足下列条件的序列个数
1)序列由A、B、C、D四个字母组成;
2)序列中A和C的个数和为偶数;
整个序列数比较庞大,最终结果输出为总序列数模1000000007后的值。

例:n=2时,序列数为8个,有BB、BD、DB、DD、AA、AC、CA、CC

输入数据
2

输出数据
8

多写几个n就会发现规律,序列分为两类:只由B、D两个字母组成的序列和包含A、C的序列。前一种序列数易得为2^n个。后面一个序列数比较难求,需要根据序列长度来判断。它可以被认为是选x个A或C(x为偶数,数量与前一种序列的序列数相同,都是2的n次方),以及n-x个第一种序列交叉组成而成。交叉方式相当于从n个位置中选择x种位置。
从上面的分析可以看出,两类序列其实符合同一种情况,总序列数可以由一个公式得到,即 2 n ∑ x = 0 n C n x 2^n\sum_{x=0}^nC_{n}^x 2nx=0nCnx(x为0到n的偶数)
上面公式可以看到,前一种序列只是后一种序列的特殊情况,即x=0或x=n(n为偶数)时候的情形。

#include <iostream>
using namespace std;
int main()
{
	int i,j,n;
	long long int sum1,sum2,mul;
	while (cin>>n)
	{
		sum1=1;
		for (i=0;i<n;i++)
			sum1=(sum1*2)%1000000007;
		sum2=0;
		for (i=0;i<=n;i++)
		{
			if (!(i%2))
			{
				mul=1;
				for (j=0;j<i;j++)
					mul=(mul*(n-j)/(j+1))%1000000007;
				sum2=(sum2+mul)%1000000007;
			}
		}
		cout<<(sum1*sum2)%1000000007<<endl;
	}
}

思考花的时间比较长,没来的及优化算法,n数字大于10000就超时了。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值