首页 > 技术文章 > [LOJ2538][PKUWC2018]Slay the Spire(DP)

HocRiser 2018-12-30 00:13 原文

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 }

 

推荐阅读