洛谷P4071 [SDOI2016]排列计数【组合数学+错排】

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/niiick/article/details/82748012

时空限制 1000ms / 128MB

题目描述

求有多少种长度为 n 的序列 A,满足以下条件:

1 ~ n 这 n 个数在序列中各出现了一次

若第 i 个数 A[i] 的值为 i,则称 i 是稳定的。序列恰好有 m 个数是稳定的

满足条件的序列可能很多,序列数对 10^9+710
9
+7 取模。

输入格式:

第一行一个数 T,表示有 T 组数据。

接下来 T 行,每行两个整数 n、m。

输出格式:

输出 T 行,每行一个数,表示求出的序列数


题目分析

明明就是数学题为什么都说是DP

思路并不难
我们假设已经有m个数稳定
那么剩下n-m个数都必须不在自己位置上,显然就是错排D[n-m]

而确定一开始哪m个数是稳定的
显然有 C n m C_n^m 种选法

根据乘法原理有 a n s = C n m D [ n m ] ans=C_n^m*D[n-m]
考虑到n,m和模数都较大,所以可以先预处理阶乘计算组合数

关于错拍

D [ n ] D[n] 表示 1 1 ~ n n 的错排方案数
则其有递推式 D [ n ] = ( n 1 ) ( D [ n 1 ] + D [ n 2 ] ) D[n]=(n-1)*(D[n-1]+D[n-2])

证明

假如我们要错排 1 1 ~ n n
我们先将1错排(即将1放到 2 2 ~ n n 中某个位置),共n-1种方案

假设上一步将1放在了第k位
下一步有两种情况
1.将k放到1号位,那么问题变为剩下n-2个数的错排方案数D[n-2]
2.k不放1号位,那么我们将1号位视为k号位,那么问题转化为剩下n-1个数的错排方案数D[n-1]

根据乘法与加法原理有 D [ n ] = ( n 1 ) ( D [ n 1 ] + D [ n 2 ] ) D[n]=(n-1)*(D[n-1]+D[n-2])


#include<iostream>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long lt;

lt read()
{
    lt f=1,x=0;
    char ss=getchar();
    while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
    while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
    return f*x;
}

const int mod=1e9+7;
const int maxn=1000010;
int t;
lt fac[maxn],D[maxn],inv[maxn];

lt qpow(lt a,lt k,lt p)
{
    lt res=1;
    while(k>0){
        if(k&1) res=(res*a)%p;
        a=(a*a)%p;
        k>>=1;
    }
    return res;
}

lt C(lt n,lt m){ return fac[n]*inv[m]%mod*inv[n-m]%mod;}

int main()
{
    t=read(); fac[0]=1;
    for(int i=1;i<=maxn;++i) 
    {
        fac[i]=fac[i-1]*i%mod;
        inv[i]=qpow(fac[i],mod-2,mod); 
    }
    
    D[0]=D[1]=0; D[2]=1;
    for(int i=3;i<=maxn;++i)
    D[i]=(i-1)*(D[i-2]+D[i-1])%mod;
    
    while(t--)
    {
        lt n=read(),m=read();
        if(n-m==1) printf("0\n");
        else if(m==n) printf("1\n");
        else if(m==0) printf("%lld\n",D[n]);
        else printf("%lld\n",C(n,m)*D[n-m]%mod);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/niiick/article/details/82748012
今日推荐