CF2025E Card Game 题解
太喜欢这个题了,这个题出得很启发性,我以前还没见过,于是把这个题记录下来。
题面
在伯兰最流行的纸牌游戏中,使用的是一副 \(n \times m\) 纸牌。每张牌都有两个参数:花色和等级。游戏中花色的编号从 \(1\) 到 \(n\),等级的编号从 \(1\) 到 \(m\)。每种花色和等级的组合都有一张牌。
- \(a = 1\), \(c \ne 1\) (花色为 \(1\) 的牌可以战胜其他花色的牌);
- \(a = c\), \(b > d\) (一张牌可以击败同花色但等级较低的任何其他牌).
两名玩家进行游戏。游戏开始前,他们每人正好得到一半的牌。如果第一位玩家可以为第二位玩家的每一张牌选择一张可以击败它的牌,并且没有被选择两次的牌(即第一位玩家的牌与第二位玩家的牌存在配对,在每一对牌中,第一位玩家的牌击败第二位玩家的牌),则第一位玩家获胜。否则,第二名玩家获胜。
你的任务是计算有多少种分配牌的方法能让第一名玩家获胜。如果有一张牌在一种分配方式中属于第一名玩家,而在另一种分配方式中属于第二名玩家,那么这两种分配方式就被认为是不同的。方法的数量可能非常大,输出答案对 \(998244353\) 的模。
唯一一行包含两个整数 \(n\) 和 \(m\) (\(1 \le n, m \le 500\)) 为偶数。
输入的其他限制条件:\(m\) 为偶数。
题解
这个题乍一看很 \(dp\) 但是实际上这个题可以用组合数学推出答案。
对同样花色的牌,考虑什么情况下才能获胜,显然是对于所有的先手 (\(A\)) 的牌都可以找到一个后手 (\(B\)) 的牌使得 \(A\) 的牌面比 \(B\) 大,考虑括号匹配。
对于任意一个前缀 \(A\) 选择第 \(i\) 张牌则第 \(i\) 位置为左括号,否则被 \(B\) 选择就是右括号,对于任意前缀,必定满足左括号数不小于右括号数,考虑状态转移。
记 \(dp[i][j]\) 表示考虑的前 \(i\) 个位置,其中有 \(j\) 个左括号赘余(没有被右括号匹配),则对于下一个位置要么增加一个左括号,要么减少一个左括号,状态转移如下:
\]
我们选择第一行的牌(花色为 \(1\))的时候的所有情况被 \(dp\) 数组所包含,接下来考虑剩下第 \(2 \sim n\) 行的牌,此部分 \(A\) 必不可能多选,否则必定存在一张牌不能在同行匹配,会被 \(B\) 用一张 \(1\) 匹配,所以此时右括号赘余,考虑前面所有 \(A\) 的牌会被抵消掉,仅仅把多余的牌替换为 \(B\) 的牌即可,也就是说这一部分的贡献和第一行完全一样,考虑对第 \(2 \sim n\) 行的方案数卷积,即:
\]
这个转移是直觉的,因为对两行分别赘余 \(x\), \(y\) 张牌,总共赘余的牌有 \(x + y\) 张,而由于所有的行是相同的,做 \(n - 1\) 次卷积:
\]
最后我们的答案需要第一行赘余的左括号与其余行赘余的右括号完全匹配,可以列出:
\]
参考代码(滚动数组优化)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 510;
const ll mod = 998244353;
int n, m;
int main()
{
cin >> n >> m;
vector<ll> dp(m + 1), f(m + 1);
dp[0] = f[0] = 1;
for (int i = 0; i < m; i ++ )
{
vector<ll> tmp(m + 1);
for (int j = 0; j <= i; j ++ )
{
(tmp[j + 1] += dp[j]) %= mod;
if (j) (tmp[j - 1] += dp[j]) %= mod;
}
swap(tmp, dp);
}
for (int i = 1; i < n; i ++ )
{
vector<ll> tmp(m + 1);
for (int x = 0; x <= m; x ++ )
for (int y = 0; x + y <= m; y ++ )
(tmp[x + y] += f[x] * dp[y] % mod) %= mod;
swap(tmp, f);
}
ll ans = 0;
for (int i = 0; i <= m; i ++ ) (ans += dp[i] * f[i] % mod) %= mod;
cout << ans;
return 0;
}
CF2025E Card Game 题解的更多相关文章
- Clash Credenz 2014 Wild Card Round题解
A题 简单模拟. /************************************************************************* > File Name: ...
- CF1492B Card Deck 题解
Content 有 \(n\) 张纸牌组成的一个牌堆,每张纸牌都有一个价值 \(p_1,p_2,\dots,p_n\).每次选出最顶上的几个牌放到另外一个一开始为空的牌堆里面.定义一个牌堆的总值为 \ ...
- CF106A Card Game 题解
Content 一种纸牌游戏有许多张卡牌,每张卡牌有一个套装(S,H,D和 C)和一个等级(按升序排列6,7,8,9,T, J,Q,K,A). 规定以下情况卡牌 A 才能赢卡牌 B: A 有王牌套装, ...
- MinMax 容斥 学习笔记
基本形式 \[ \max(S) = \sum_{T\subseteq S, T \neq \varnothing} (-1)^{|T|-1}\min(T) \] 证明 不提供数学证明. 简要讲一下抽象 ...
- 【题解】P3129高低卡(白金)High Card Low Card
[题解][P3129 USACO15DEC]高低卡(白金)High Card Low Card (Platinum) 考虑贪心. 枚举在第几局改变规则,在改变规则之前,尽量出比它大的最小的牌,在改变规 ...
- HDU 4336 Card Collector(状压 + 概率DP 期望)题解
题意:每包干脆面可能开出卡或者什么都没有,一共n种卡,每种卡每包爆率pi,问收齐n种卡的期望 思路:期望求解公式为:$E(x) = \sum_{i=1}^{k}pi * xi + (1 - \sum_ ...
- 【题解】HDU4336 Card Collector
显然,这题有一种很简单的做法即直接状压卡牌的状态并转移期望的次数.但我们现在有一个更加强大的工具——min-max容斥. min-max 容斥(对期望也成立):\(E[max(S)] = \sum_{ ...
- [OpenJudge 3061]Flip The Card
[OpenJudge 3061]Flip The Card 试题描述 There are N× Ncards, which form an N× Nmatrix. The cards can be p ...
- cdoj 31 饭卡(card) 01背包
饭卡(card) Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/31 Des ...
- 《ACM国际大学生程序设计竞赛题解Ⅰ》——基础编程题
这个专栏开始介绍一些<ACM国际大学生程序设计竞赛题解>上的竞赛题目,读者可以配合zju/poj/uva的在线测评系统提交代码(今天zoj貌似崩了). 其实看书名也能看出来这本书的思路,就 ...
随机推荐
- Https通信的SSL证书工作流程原理(转)
前言 浏览器与服务器之间的https加密通信会包括以下一些概念:非对称加密.对称加密.RSA.证书申请.根证书.https证书加密,就是在传输层tcp和应用层http之间加了一层ssl层来对传输内容进 ...
- 【转】如何在ASP.NET Core自定义中间件中读取Request.Body和Response.Body的内容?
文章名称: 如何在ASP.NET Core自定义中间件读取Request.Body和Response.Body的内容?作者: Lamond Lu地址: https://www.cnblogs.com/ ...
- 【YashanDB知识库】outline固化执行计划
[问题分类]性能优化,功能使用 [关键字]outline [问题描述]防止SQL执行计划突变,用outline固化执行计划 [问题原因分析]防止SQL执行计划突变,用outline固化执行计划 [解决 ...
- .NET 多版本兼容的精美 WinForm UI控件库
前言 有粉丝小伙伴在后台留言咨询有没有WinForm 控件库推荐,现在就给安排上. .NET 平台进行 Windows 应用程序开发的我们来说,找一个既美观又实用的 WinForm UI 控件库至关重 ...
- 小忙半个月搞个CKA,可还行,搞完后发现自己被割韭菜了
- 小tips:ECMA-262定义的7种错误类型
七种错误类型如下: Error EvalError RangeError ReferenceError SyntaxError TypeError URIError 其中,Error是基类型(其他六种 ...
- 技术储备--SPI接口硬件协议栈芯片W5500使用
整体思路: 移植官方软件包代码, 配置好底层的SPI收发函数以及片选脚操作, 至于临界区操作函数,根据实际情况进行添加,也可以不加. 这就移植好了,就可以在我们自己的板子上跑官方的示例程序了. 官方软 ...
- 在 Node.js 中使用 ES6 模块 import 和 export
1.Node版本 >= 13 2.使用 ES6 模块 a.js export const A = 'A'; index.js import { A } from './a.js'; consol ...
- 深入理解Android MTP之存储映射分析
深入理解Android MTP之UsbService启动分析 分析了MTP的服务端的启动,本文来分析切换MTP模式后,存储中的数据(文件.目录)是如何映射到PC端的. 首先你得知道如何切换MTP模式. ...
- 精彩回顾|【2023 ACDU 中国行·深圳站】数据库主题交流活动成功举办!
6月30日下午,[ACDU 中国行·深圳站]在深圳回酒店圆满落下帷幕.本次活动由中国数据库联盟(ACDU)联合墨天轮社区主办,围绕「数据库前沿技术揭秘及应用」这一主题,七位数据库行业的领军人物从数据库 ...