【Luogu】P2490黑白棋(博弈DP)
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<cctype> #define mod 1000000007 #define maxn 10020 using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } long long mul[maxn]; long long inv[maxn]; long long f[21][maxn]; inline long long Pow(long long a,long long b){ long long ret=1; while(b){ if(b&1) ret=ret*a%mod; a=a*a%mod; b>>=1; } return ret; } inline long long C(long long n,long long m){ return (mul[n]*inv[m]%mod)*inv[n-m]%mod; } int main(){ int n=read(),e=read()>>1,w=read(); mul[0]=inv[0]=1; for(int i=1;i<=n;++i){ mul[i]=mul[i-1]*i%mod; inv[i]=Pow(mul[i],mod-2); } f[0][0]=1; for(int i=0;i<=14;++i){ for(int j=0;j<=n-(e<<1);++j){ //printf("%d %d\n",i,j); for(int k=0;k*(w+1)<=e&&j+k*(w+1)*(1<<i)<=n-(e<<1);++k){ long long &now=f[i+1][j+k*(w+1)*(1<<i)]; now=(now+f[i][j]*C(e,k*(w+1)))%mod; } } } long long ans=0; for(int i=0;i<=n-(e<<1);++i) ans=(ans+f[14][i]*C(n-i-e,e))%mod; printf("%lld\n",(C(n,e<<1)-ans+mod)%mod); return 0; }