首先不可重的整数规划是fi,j=fi-1,j-i+fi,j-i的
然后现在加了一个限制,分成的数不能超过n,那么对于拼大于n的数的时候多减一个fi-1,j-n-1
接下来是优化代码暴露我自带巨大常数的时候了
拿着两份代码看来看去蒙蔽了,为啥我要跑10s人家2s就完事了。。。
//memset(f,0,sizeof(f));
....................
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; const int mod=1e9+7; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } LL f[20][1100000]; int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); int T; T=read(); while(T--) { int n,k,li,mod; n=read(),k=read(),mod=read(),li=n*k; f[0][0]=1; for(int i=1;i<=k;i++) for(int j=i;j<=li;j++) { f[i][j]=f[i-1][j-i]+f[i][j-i]; if(j>n)f[i][j]=f[i][j]-f[i-1][j-n-1]+mod; f[i][j]%=mod; } LL ans=0; for(int i=0;i<=k;i++) for(int j=i;j<=li;j++) { ans+=f[i][j]*f[k-i][j]; ans%=mod; if(i<k)ans+=f[i][j]*f[k-i-1][j],ans%=mod; } printf("%lld ",ans); } return 0; }