题解【P6870 [COCI2019-2020#5] Zapina】

· · 题解

题意

n不同的人和 n不同的题。

i 个人开心当且仅当他被分配到 i 道题。

求让至少一个人开心的分配方案数。

思路

显然 dp。

f(i,j) 表示前 i 个人分配 j 道题且至少已经有一个人开心的方案数。

考虑转移:

官方题解也是这种思路。

code

#include<stdio.h>
#define N 351
#define mod 1000000007
int n,c[N][N],ans[N][N];
inline int ksm(long long a,int b)
{
    long long ans=1;
    for(;b;b>>=1,a*=a,a%=mod)if(b&1)ans*=a,ans%=mod;
    return ans;
}
main()
{
    scanf("%d",&n);
    for(int i=0;i<=n;++i)
    {
        c[i][0]=c[i][i]=1;
        for(int j=1;j<i;++j)c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
    }
    ans[1][1]=1;
    for(int i=2;i<=n;++i)for(int j=1;j<=n;++j)
    {
        if(j>=i)ans[i][j]=1ll*c[j][i]*ksm(i-1,j-i)%mod;//使i开心
        for(int k=0;k<=j;++k)if(i!=k)//使i不开心
            ans[i][j]=(ans[i][j]+1ll*ans[i-1][j-k]*c[j][k])%mod;
    }
    printf("%d",ans[n][n]);
}