【题解】4465 [Jsoi2013]游戏中的学问

原题传送门

线性dp推一推就推出方程

\(f[i][j]\)表示有\(j\)个人,分成\(i\)组,一共有多少分发

边界为\(f[0][0]=1\),珂以得出方程为\(f[i][j]=(j-1)*(j-2)*f[i-1][j-3]+(j-1)*f[i][j-1]\)

#include <bits/stdc++.h>
#define getchar nc
using namespace std;
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf; 
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; 
}
inline int read()
{
    register int x=0,f=1;register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x*f;
}
inline void write(register int x)
{
    if(!x)putchar('0');if(x<0)x=-x,putchar('-');
    static int sta[20];register int tot=0;
    while(x)sta[tot++]=x%10,x/=10;
    while(tot)putchar(sta[--tot]+48);
}
long long f[1005][3005];
int main()
{
    int n=read(),k=read(),p=read();
    f[0][0]=1;
    for(register int i=1;i<=k;++i)
        for(register int j=i*3;j<=n;++j)
            f[i][j]=(1ll*(j-1)*(j-2)%p*f[i-1][j-3]%p+1ll*(j-1)*f[i][j-1]%p)%p;
    write(f[k][n]);
    return 0;
}
posted @ 2019-01-06 19:39  JSOI爆零珂学家yzhang  阅读(232)  评论(0编辑  收藏  举报