当前位置: 首页 > news >正文

[AGC022F] Checkers 题解

\(\text{[AGC022F] Checkers 题解}\)

近一段时间以来做过的最抽象的题目。

首先我们发现合并次数是 \(n-1\) 次,因此我们可以把这个东西抽象成一棵树来处理。具体地,对于 \(A\) 关于 \(B\) 对称,令 \(B\)\(A\) 连边。那么答案实际上就是根的值。发现答案一定形如 \(\sum c_i2^{d_i}\) 的形式,其中 \(c\in\{-1,1\}\)。寻找影响 \(c\) 的因素,不难发现影响它的有自己的一坨儿子的取反和在自己的祖先处不停地取反。考虑每个位置的 \(c\) 是困难的,注意到叶子节点的 \(c\) 恒定,考虑维护父子间 \(c\) 的关系(相等或不相等)。那么从下往上就变得困难,我们从上往下维护,维护每个点最终是否与其父亲的正负性相同。那么下边的 \(c_i\) 都表示与父亲的关系。

下面我们要发现一些性质,记 \(son_i\) 表示 \(i\) 的儿子个数:

  • 当且仅当 \(son_i\) 为奇数时,\(c_i\) 取反。

这个东西的理解是你手玩一下,列出从左往右变化的式子就能发现。

  • 儿子间相邻位置 \(c_i\) 不同

这里的不同指的是不考虑儿子子树内的 \(c\),那么每一次变换时都会将上一个取反,后面会捆在一起取反,因此得到这个结论。

那么我们现在可以开始 dp 了。我们设 \(dp_{i,j}\) 表示考虑前 \(i\) 个数,最外层有 \(j\)\(son_x\) 为奇数的方案数。那么枚举下一层的节点个数为 \(k(k\ge j)\),那么考虑到满足儿子个数为奇数的时候这个点会满足儿子 \(c\) 的取值和父亲相等的会比不相等的多一个,那么会有下一层与父亲 \(c\) 相同的个数为 \(t=\frac{k-j}2\),要满足 \(2|k-j\)

现在的问题是考虑要解决此时扩展的节点中有多少个节点满足儿子个数为奇数。先枚举实际情况下与父亲 \(c\) 相同的点的个数 \(p\),这个实际情况下指的是考虑儿子内部转移的情形,那么能得到的下一层中儿子个数为奇数的点的数量要 \(\ge|t-p|\),原因是考虑儿子个数为奇数可以改变当前 \(c\) 的奇偶性,那么按照 \(t,p\) 的大小分类讨论一下可以得到这个东西的正确性。但是这里我们只向 \(|t-p|\) 而不是 \(|t-p|+2r\) 转移,原因是形态不同的树权值有可能相同,那么我们只统计个数最小的情形是有正确性的。

那么给出转移式:

\[dp_{i,j}{n-i\choose k}{k\choose p}\to dp_{i+k,|t-p|} \]

初始状态是 \(dp_{1,0}=dp_{1,1}=n\),答案是 \(dp_{n,0}\),复杂度是 \(O(n^4)\)

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 55, mod = 1e9 + 7;
int n;
int C[N][N], dp[N][N];
void add(int &x, int y) {x = (x + y) % mod;
}
signed main() {cin >> n;C[0][0] = 1;for (int i = 1; i <= n; i++)for (int j = 0; j <= i; j++)C[i][j] = ((j == 0 ? 0 : C[i - 1][j - 1]) + C[i - 1][j]) % mod;dp[1][0] = dp[1][1] = n;for (int i = 1; i <= n; i++)for (int j = 0; j <= i; j++)for (int k = j ? j : 2; i + k <= n; k += 2) {int t = (k - j) >> 1;for (int p = 0; p <= k; p++) add(dp[i + k][abs(t - p)], dp[i][j] * C[n - i][k] % mod * C[k][p] % mod);}cout << dp[n][0] <<'\n';return 0;
}
http://www.rkmt.cn/news/3875.html

相关文章:

  • 程序员的副业变现之路:我的双平台矩阵打法
  • MyBatis注解的运用于条件搜索实践
  • 利用k8s client-go库创建CRD的informer的操作流程
  • Golang并发编程及其高级特性
  • 元推理agi不是象人思维,而是教人思维,人类脸上挂不住啊
  • 优惠券
  • 基于ArcGIS Pro SDK 3.4.2 + C# + .NET 8 的自动化制图系统初探
  • 单例模式:线程安全,以及volatile关键字
  • 用 Python 和 Tesseract 实现验证码识别
  • 基于 Weiler–Atherton 算法的 IoU 求解
  • 25.9.13 字符编码标准
  • 哭了,散了,明白了
  • 用 Java 和 Tesseract 实现验证码识别
  • Microsoft-Activation-Scripts,好用,记录一下。
  • 9.13 模拟赛 T3
  • Docker应用 - FileBrowser
  • Cmake介绍
  • 项目案例作业1:学生信息管理系统(面向对象初步接触)
  • Linux网络:初识网络 - 详解
  • 20250909比赛总结
  • 手动下载vscode扩展的方法
  • CF1583F Defender of Childhood Dreams
  • scrollArea无法滚动
  • 【置顶】欢迎来到 ziyaojia 的主页
  • ZYNQ Ultrascale+系列部署yolo v10(暂定,若过于艰难则考虑降级或FQ)
  • 【EF Core】再谈普通实体关系与 Owned 关系的区别
  • qoj6104 Building Bombing
  • Cursor小程序实战系列三: 前后端对接保姆级拆解
  • 课前问题思考2
  • Cursor小程序实战四:如何让AI写好后端代码