一个 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;
}