[LOJ2538][PKUWC2018]Slay the Spire(DP)
https://blog.csdn.net/maxwei_wzj/article/details/80789619
感觉主要难在想到通过f,g来求F,G。
代码实现调换了题解中f,g的两维。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 6 typedef long long ll; 7 using namespace std; 8 9 const int N=3010,mod=998244353; 10 int T,n,m,k,ans,C[N][N],wg[N],wf[N],g[N][N],f[N][N],sg[N][N],sf[N][N]; 11 12 bool cmp(int a,int b){ return a>b; } 13 14 int G(int x,int y){ 15 if (x>n || x<y) return 0; 16 if (!y) return C[n][x]; 17 int res=0; 18 rep(i,1,n) res=(res+1ll*g[y][i]*C[n-i][x-y])%mod; 19 return res; 20 } 21 22 int F(int x,int y){ 23 if (x>n || x<y) return 0; 24 int res=0; 25 rep(i,1,n) res=(res+1ll*f[y][i]*C[n-i][x-y])%mod; 26 return res; 27 } 28 29 int main(){ 30 freopen("slay.in","r",stdin); 31 freopen("slay.out","w",stdout); 32 for (scanf("%d",&T); T--; ){ 33 scanf("%d%d%d",&n,&m,&k); ans=0; C[0][0]=1; 34 rep(i,1,n){ C[i][0]=1; rep(j,1,i) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod; } 35 rep(i,1,n) scanf("%d",&wg[i]); 36 rep(i,1,n) scanf("%d",&wf[i]); 37 sort(wg+1,wg+n+1,cmp); sort(wf+1,wf+n+1,cmp); 38 rep(i,0,n) rep(j,0,n) f[i][j]=g[i][j]=sf[i][j]=sg[i][j]=0; 39 rep(i,0,n) g[0][i]=sg[0][i]=1; 40 rep(i,1,k) rep(j,i,n) 41 g[i][j]=1ll*wg[j]*sg[i-1][j-1]%mod,sg[i][j]=(sg[i][j-1]+g[i][j])%mod; 42 rep(i,1,k) rep(j,i,n) 43 f[i][j]=(1ll*wf[j]*C[j-1][i-1]%mod+sf[i-1][j-1])%mod,sf[i][j]=(sf[i][j-1]+f[i][j])%mod; 44 rep(i,0,k-1) ans=(ans+1ll*G(i,i)*F(m-i,k-i))%mod; 45 rep(i,k,m-1) ans=(ans+1ll*G(i,k-1)*F(m-i,1))%mod; 46 printf("%d\n",ans); 47 } 48 return 0; 49 }