排列组合——成都七中DAY6-Test

4 篇文章 0 订阅
1 篇文章 0 订阅

题目


题解:

前30%的数据:存下阶乘以及阶乘的逆元,每次暴力做就好了。 
 
前100%的数据: 
这算是一道考察思维的题目,思路源自于一道文化课题目,原题的答案做法是暴力推式子。当时想到了这样一个比较优秀的做法,对思维具有很好的启发作用,即考虑式子的组合意义。 
首先考虑,将C(n,i)*C(n,i)换成C(n,i)*C(n,n-i)。这样的话,就是对于每个 i,计算n个
中选i个的方案数乘上 n个中选(n-i)个的方案数,最后累加起来。

这样得到的答案,实际上相当于2n个物品, 在前 n个中选i个, 在后 n个中选(n-i)个, 又由于i取遍0~n 所有整数,
那么累加后方案数就等于C(2n,n)。 

所以每次输出C(2n,n)即可,同样预处理阶乘及逆元,复杂度O(n*log+T)。 
 
实际上这道题打表找规律说不定也能找到规律。 

果然满脑子暴力求组合数的我还是太菜了...


代码:

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<iostream>
#define ll long long
using namespace std;
const int p=1000000007;
int jc[2000005],ni[2000005],T;
int pow(int a,int b)
{
	int re=1,t=a;
	while(b)
	{
		if(b&1) re=1ll*re*t%p;
		t=1ll*t*t%p;
		b>>=1; 
	}
	return re;
}
ll C(int n,int m)
{
	return 1ll*jc[n]*ni[m]%p*ni[n-m]%p;
}
int main()
{
	jc[0]=1;
	for(int i=1;i<=2000001;i++) jc[i]=1ll*jc[i-1]*i%p;
	ni[2000001]=pow(jc[2000001],p-2);	 
	for(int i=2000000;i>=0;i--) ni[i]=1ll*ni[i+1]*(i+1)%p;
	scanf("%d",&T);
	while(T--)
	{
		int n;
		scanf("%d",&n);
		if(n==0) printf("1\n");
		else printf("%lld\n",2*C(2*n-1,n)%p);
	}
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值