通过杨辉三角求组合数

一个 1 到 n 的排列被称为半递增序列,是指排列中的奇数位置上的值单调递增,偶数位置上的值也单调递增。
例如:(1, 2, 4, 3, 5, 7, 6, 8, 9) 是一个半递增序列,因为它的奇数位置上的值是 1, 4, 5, 6, 9,单调递增,偶数位置上的值是 2, 3, 7, 8,也是单调递增。
请问,1 到 n 的排列中有多少个半递增序列?
输入格式
输入一行包含一个正整数 n。
输出格式
输出一行包含一个整数,表示答案,答案可能很大,请输出答案除以 1000000007 的余数。
样例输入
5
样例输出
10
样例说明
有以下半递增序列:
 (1, 2, 3, 4, 5)
 (1, 2, 3, 5, 4)
 (1, 2, 4, 3, 5)
 (1, 3, 2, 4, 5)
 (1, 3, 2, 5, 4)
 (1, 4, 2, 5, 3)
 (2, 1, 3, 4, 5)
(2, 1, 3, 5, 4)
(2, 1, 4, 3, 5)
(3, 1, 4, 2, 5)
评测用例规模与约定
对于 50% 的评测用例,2 <= n <= 20。
对于所有评测用例,2 <= n <= 1000。


题解;通过题目我们可以知道只要奇数位置上的值单调递增,偶数位置上的值也单调递增。这个数组就是一个半递增序列。

这道题我们可以看成一个基础数学的排列组合问题。

假设已知一共1000个数,奇数位是500个,我们可以在1000个数中选择500个递增的数放到这些奇数位上,如果奇数位已经排列好那么我们的偶数就只能排剩下的500个数,并且只有一种方法(因为要递增)。

由于C(n,m)=C(n-1,m-1)+C(n-1,m)。由于数据太大无法直接乘除,如C1000500的数太大了,已经远远超出int,而且还要取模,对于除法的取模也是很复杂的,我们这里可以采用杨辉三角解决这个组合问题。

 

代码如下:

#include<iostream>
using namespace std;
const int k=1e9;
int fan[100000]={0};
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		fan[0]=1;
		fan[i]=1;
		for(int j=i-1;j>0;j--){
			fan[j]=(fan[j]+fan[j-1])%k;
		}
	}
	cout<<fan[n/2]<<endl;
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值