LA 5092 Permutation Counting

来源:互联网 发布:淘宝蓝冠和皇冠的区别 编辑:程序博客网 时间:2024/05/07 14:12

1.题目描述:点击打开链接

2.解题思路:本题就是Eulerian Number,《具体数学》中有讲解。也可参考维基百科中的链接:点击打开链接 设f(n,k)表示1~n的排列中有k个欧拉数的方案数。那么有如下递推式:

f(n,k)=(1+k)*f(n-1,k)+(n-k)*f(n-1,k-1);

不含n的排列中:如果在该排列的升序或者该排列的开始位置插入n,那么k值不变。如果在降序或者最后位置插入n,那么k变成k+1。当f(n-1,k)时候,共有k个升序位置和开始位置可以插入n,使得k不变,当为f(n-1,k-1)的时候,共有n-k-1个降序位置,加上一个结尾位置共有n-k个位置可以插入n,使得k-1变成k。

3.代码:

#include<iostream>#include<algorithm>#include<cassert>#include<string>#include<sstream>#include<set>#include<bitset>#include<vector>#include<stack>#include<map>#include<queue>#include<deque>#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<cctype>#include<complex>#include<functional>#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define rep(i,n) for(int i=0;i<(n);i++)#define me(s) memset(s,0,sizeof(s))#define pb push_back#define lid (id<<1)#define rid (id<<1|1)typedef long long ll;typedef pair<int,int> P;const int N=1000+10;const int MOD=1000000007;ll f[N][N];void init(){    f[1][0]=1;    f[1][1]=0;    for(int i=2;i<1001;i++)    {        f[i][0]=1;        f[i][i]=0;        for(int j=1;j<i;j++)            f[i][j]=((1+j)*f[i-1][j]+f[i-1][j-1]*(i-j))%MOD;    }}int main(){    int n,k;    init();    while(~scanf("%d%d",&n,&k))    {        printf("%lld\n",f[n][k]);    }}



0 0
原创粉丝点击