首页 > 其他分享 >题解:CF2025E Card Game

题解:CF2025E Card Game

时间:2024-11-13 17:31:20浏览次数:1  
标签:花色 int 题解 路径 Game res CF2025E 卡特兰 mod

在这

貌似和大部分做法不太一样(?)


权当卡特兰数的复习题吧。不会卡特兰数的可以先看文末。


如果没有花色 \(1\) 这道题就很简单了,对于每个别的花色都有 \(C(m)\) 种分配方案。\(C(n)\) 表示卡特兰数的第 \(n\) 项,答案就是乘起来。

发现除了花色 \(1\) 每种花色的牌都是独立的。这启示我们枚举每种牌用了多少张花色 \(1\)。设 \(f_{i,j}\) 表示前 \(i\) 种花色的牌用了 \(j\) 张花色 \(1\) 能使第一名玩家获胜的方案数。

有转移:

\[f_{i,j}=\sum_{k\le j} f_{i-1,j-k} \times H(k) \]

枚举的 \(k\) 的含义为第 \(i\) 个花色用了 \(k\) 张花色 \(1\)。其中 \(H(k)\) 表示用了 \(k\) 张花色 \(1\) 的分配方案。

\(H(k)\) 的计算也是简单的,考虑卡特兰数的经典问题,不能经过直线 \(y=x\) 的方格路计数(如果不会可以看文末)。我们先得到了 \(k\) 张极大的牌,可以看做在网格中先向右走了 \(k\) 步,那问题就成了从 \((0,k)\) 走到 \((\frac{m+k}{2},\frac{m+k}{2})\) 且不能经过直线 \(y=x\) 的方案数。

答案就是:

\[H(k)={m \choose \frac{m+k}{2}}-{m\choose\frac{m+k}{2}+1} \]

至此,已经解决大部分问题了,最后就是解决花色 \(1\) 的分配。上面的问题是 \(m\) 张牌中需要先拿出 \(k\) 张与花色 \(1\) 匹配,而现在的问题是 \(m\) 张花色 \(1\) 需要拿出若干张与其他牌匹配,发现问题是一样的,统计答案时乘上 \(H(k)\) 就好了,这里的 \(k\) 表示有 \(k\) 张花色 \(1\) 被用来与其他花色的牌匹配。

复杂度为 \(O(n^3)\),如果你是大常数选手就会 TLE,有一个优化是 \(\frac{m+k}{2}\) 为整数的状态才合法,加上这个就不卡常了。

#include <bits/stdc++.h>

using namespace std;

const int maxN = 1e3 + 7, mod = 998244353;

int fc[maxN], ifc[maxN];
int ksm(int a, int b = mod - 2) {
  int res = 1;
  while (b) {
    if (b & 1)
      res = 1ll * res * a % mod;
    a = 1ll * a * a % mod;
    b >>= 1;
  }
  return res;
}

int n, m;

int C(int n, int m) {
  if (n < 0 || m < 0 || n < m) return 0;
  return 1ll * fc[n] * ifc[m] % mod * ifc[n - m] % mod;
}
int H(int k) {
  auto res = C(m, (m + k) / 2) - C(m, (m + k) / 2 + 1);
  res += res < 0 ? mod : 0;
  return res;
}

int f[507][507];

signed main() {
  ios::sync_with_stdio(false), cin.tie(nullptr);

  cin >> n >> m;

  fc[0] = 1;
  for (int i = 1; i <= m * 2; i++)
    fc[i] = 1ll * fc[i - 1] * i % mod;
  ifc[m * 2] = ksm(fc[m * 2]);
  for (int i = m * 2 - 1; i >= 0; i--)
    ifc[i] = 1ll * ifc[i + 1] * (i + 1) % mod;

  f[1][0] = 1;
  for (int i = 2; i <= n; i++)
    for (int j = 0; j <= m; j++)
      for (int k = (m & 1); k <= j; k += 2)
        f[i][j] = (f[i][j] + 1ll * f[i - 1][j - k] * H(k) % mod) % mod;

  int ans = 0;
  for (int k = 0; k <= m; k++)
    ans = (ans + 1ll * f[n][k] * H(k) % mod) % mod;
  cout << ans << '\n';
}

卡特兰数可以解决这类问题:有一个大小为 \(n\times n\) 的方格图左下角为 \((0, 0)\) 右上角为 \((n, n)\) ,从左下角开始每次都只能向右或者向上走一单位,不走到对角线 \(y=x\) 上方(但可以触碰)的情况下到达右上角有多少可能的路径?(摘自 OI Wiki)

答案就是所有的路径数减去不合法的路径数,发现不合法的路径一定经过直线 \(y=x+1\)。对于经过 \(y=x+1\) 且终点为 \((n,n)\) 的路径,在它第一次接触 \(y=x+1\) 后,把它的所有运动反向,向右走变为向上走,向上走变为向右走,最后它一定会到达 \((n-1,n+1)\)。

下图中的橙色虚线和粉色虚线是不合法的路径。

可以得出 \(C(n)\) 为从 \((0,0)\) 到 \((n,n)\) 的路径数减从 \((0,0)\) 到 \((n-1,n+1)\) 的路径数。

所以:

\[C(n)={2n\choose n}-{2n\choose n+1} \]

标签:花色,int,题解,路径,Game,res,CF2025E,卡特兰,mod
From: https://www.cnblogs.com/ccxswl/p/18544421

相关文章

  • P6628 [省选联考 2020 B 卷] 丁香之路 题解
    P6628[省选联考2020B卷]丁香之路题解首先考虑题目中路径权值的含义:\(i,j\)两点之间的最短路就是\(|i-j|\)直接连边。题目要求从\(s\)遍历到每个点,到终点每个\(x\)的最短时间。于是我们不妨枚举每个\(x\),考虑在\(O(n)\)至\(O(n\logn)\)的时间复杂度里解决问题......
  • 《统计每个月兔子的总数》 递归、记忆化数组、动态规划题解
    目录题目描述输入描述输出描述解析完整代码描述有一对兔子,从出生后第3个月起每个月都生一对兔子,一对小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问第n个月(n<=50)的兔子总数为多少对?输入描述输入1个整数n,表示第几个月输出描述第n个月兔子的总数量有多少?......
  • P10833 [COTS 2023] 下 Niz题解
    题意:给定长度为\(N\)的序列\(a\),求满足以下条件的\((l,r)\)对数:\(1\lel\ler\leN\);\(a_l,a_{l+1},\cdots,a_{r-1},a_r\)是\(1\simr-l+1\)的排列。\(1\leN\le10^6\);\(1\lea_i\leN\)。思路首先,“排列”本身这个性质是很强的。因为排列本身需要从1开......
  • AT_agc011_d [AGC011D] Half Reflector 题解
    用\(1\)表示A,\(0\)表示B,观察进行一次操作后字符串会发生什么变化。首先当第一个数为\(1\)时,只会将第一个数变为\(0\)。对于剩下的情况,手玩一下可以发现会将第一个数移到末尾,然后将所有数异或\(1\)。先考虑暴力怎么做,可以记一个指针\(i\)和当前应该给全体数异或的值\(......
  • P10856 【MX-X2-T5】「Cfz Round 4」Xor-Forces题解
    题意:给定一个长度为\(n=2^k\)的数组\(a\),下标从\(0\)开始,维护\(m\)次操作:给定\(x\),设数列\(a'\)满足\(a'_i=a_{i\oplusx}\),将\(a\)修改为\(a'\)。其中\(\oplus\)表示按位异或运算。给定\(l,r\),查询\(a\)的下标在\(l,r\)之间的子数组有多少颜色段。不保......
  • [题解]P3225 [HNOI2012] 矿场搭建
    P3225[HNOI2012]矿场搭建挖煤点坍塌相当于把该点和与其相连的边在图上删掉。借用wjyyy的题解,我们定义“叶子连通块”为“只包含\(1\)个割点的点双连通分量”,“非叶子连通块”为“包含\(\ge2\)个割点的点双连通分量”。如下图,橙色点是割点,红色框圈出的是点双,加粗的是叶子连通......
  • P2612 [ZJOI2012] 波浪 题解
    前置知识:连续段dp题目链接:P2612[ZJOI2012]波浪随机一个\(1\)到\(n\)的排列\(P_{1...n}\),问以下式子的值\(\lem\)的概率是多少?\[|P_1-P_2|+|P_2-P_3|+|P_3-P_4|+...+|P_{n-1}+P_n|\]输出一个答案表示概率。保留\(k\)位小数。对于\(40%\)......
  • P11071 「QMSOI R1」 Distorted Fate题解
    题意:给定一个序列,给定两种操作:将一个区间异或上一个给定的值。给定\(l,r\)求\[{\large(\sum_{i=l}^r\bigcup_{j=l}^iA_j)\bmod2^{30}}\]\(0\lea_i,x<2^{30}\),\(1\lel\ler\len\)思路由于操作数以及区间过大,一位一位地去模拟肯定是不行的。因此考虑去离线......
  • [题解]CF1407D Discrete Centrifugal Jumps
    思路注意到第二个条件和第三个条件本质相似,可以用相同的维护方式处理,因此这个只讨论第二个条件的维护方式。定义\(dp_i\)表示走到\(i\)的最少步数。第一个条件的转移显然为\(dp_i\leftarrowdp_{i-1}\)。对于第二个条件,\(i\)能向\(j\)转移,当且仅当\(h_{i+1\sim......
  • Codeforces Round 985 div1+2 个人题解(A~E)
    CodeforcesRound985div1+2个人题解(A~E)Dashboard-Refact.aiMatch1(CodeforcesRound985)-Codeforces火车头#include<bits/stdc++.h>usingnamespacestd;#defineftfirst#definesdsecond#defineyescout<<"yes\n"#definenoc......