题解:CF2025E Card Game
首先发现第 \(2\) 到 \(n\) 花色的卡牌都是等价的,不受他们花色的影响,能决定其分配方案数的是第一名玩家有多少张多余的 \(1\) 花色卡牌来换掉 \(2\) 到 \(n\) 花色的卡牌。
因此,我们可以先预处理出在得到在确定给某种花色分配 \(x\) 张 \(1\) 花色卡牌时该花色的分配方案数,记为 \(p_x\)。由于 \(2\) 到 \(n\) 不同花色的牌不能互相打,而 \(m\) 又是偶数,所以分配 \(1\) 花色卡牌数必须是偶数。考虑如何算出这个数组,除去被降维打击的牌,剩下的牌按等级从小到大排序,由于第一位玩家必须打败第二位的所有牌,我们可以视为一个长度为 \(m-x\) 的数组 \(a\),如果第 \(i\) 张牌给第一位玩家就是令 \(a_i = -1\),否则 \(a_i = 1\),求 \(a\) 的前缀和数组任意一位均大于等于 \(0\) 的方案数。这是简单的,设 \(t_{i,j}\) 表示已决定 \(a\) 的前 \(i\) 位,有 \(j\) 位为 \(-1\) 的方案数,显然有转移
显然 \(p_x\) 即为 \(t_{m,\frac{m-x}{2}}\)。
接下来考虑假如已经确定了第一位玩家一共有 \(y\) 张多余的 \(1\) 花色牌,把这些牌分配给 \(2\) 到 \(n\) 花色的方案数。设 \(f_{i,j}\) 表示已完成对 \(2\) 到 \(i\) 花色的分配,已经用了 \(j\) 张 \(1\) 花色的方案数,设在第 \(i\) 个花色分配了 \(2 \times k\) 张 \(1\) 花色牌,则有转移
最后计算答案,枚举 \(y\),由于分配第 \(1\) 类花色的牌使得有 \(y\) 张多余的方案数就是 \(p_y\),不需要再进行计算,直接乘上即可,最终答案为
#include<bits/stdc++.h>
#define MAXN 505
#define int long long
const int inf=1e18,mod=998244353;
using namespace std;
int n,m,p[MAXN],f[MAXN][MAXN],t[MAXN][MAXN],ans;
signed main(){
// freopen("card.in","r",stdin);
// freopen("card.out","w",stdout);
scanf("%lld%lld",&n,&m);
t[0][0]=1;
for(int i=1;i<=m;i++){
for(int j=0;j*2<=i;j++){
t[i][j]=t[i-1][j];
if(j>0)t[i][j]=(t[i][j]+t[i-1][j-1])%mod;
}
}
for(int i=0;i<=m;i+=2){
p[i]=t[m][(m-i)/2];
}
f[1][0]=1;
for(int i=2;i<=n;i++){
for(int j=0;j<=m;j+=2){
for(int k=0;k<=j;k+=2){
f[i][j]=(f[i][j]+f[i-1][j-k]*p[k]%mod)%mod;
}
}
}
for(int i=0;i<=m;i+=2){
int sum=p[i]*f[n][i]%mod;
ans=(ans+sum)%mod;
}
printf("%lld\n",ans);
return 0;
}
浙公网安备 33010602011771号