2.27 CW 模拟赛 T1. 麻将
前言#
- 定义合法情况, 要求输出一组合法情况 / 合法情况的最值问题 / 求方案数
- 往往利用
, 结合约束处理当前方案数- 关注构造方案 / 顺序
- 关注本质重复的转移是否存在
- 先找到一组合法解, 然后在基础上进行调整
- 找到所有情况统一的构造方案
- 往往利用
思路#
给定
求有多少种把牌划分成面子的方法
即形如
的连续段
首先因为原串上不好处理, 而且明确给了值域, 所以不难想到转移到值域上去思考
考虑一个合法解的构造过程
在值域上从前往后扫, 每次挑选符合题意的一个连续段然后对值域数组进行更新
首先, 不能简单地对值
作为 个 作为 个
以此清空 对应的数量
原因是对于一些情况
按照上面的方法, 不会考虑到先对
也就是说, 这样转移被严格限制了, 不可能生成其他情况的
因此是不行的
赛时为了解决上面的问题, 换成了对值域的区间
但是这个问题更加明显
假设对于区间
- 清空
, 在清空 - 清空
, 在清空
不难发现在本质上极容易重复, 并且不易去重
综上, 如何找到一个好的方法来
要满足两个需求
- 顺序必须严格钦定
- 必须考虑到所有可能的操作区间
因此不难想到对最初的
并不钦定一定要在当前对
不难想到状态定义
令
因为每次转移只考虑
不难发现我们可以钦定每次操作只对
这样可以避免重复
所以枚举对
然后剩下必须进行
实现#
框架#
如上转移即可
#include <bits/stdc++.h>
const int MOD = 1e9 + 7;
const int MAXN = 5206; // 41
namespace calc {
int add(int a, int b) { return a + b >= MOD ? a + b - MOD : a + b; }
int mus(int a, int b) { return a - b < 0 ? a - b + MOD : a - b; }
int mul(int a, int b) { return (a * b * 1ll) % MOD; }
void addon(int &a, int b) { a = add(a, b); }
void mulon(int &a, int b) { a = mul(a, b); }
} using namespace calc;
int n, m;
int p[MAXN];
int dp[2][MAXN][MAXN];
int now = 0, nxt = 1;
/*初始化*/
void init() {
if (m == 1 || m == 2) {
int ans = 1; for (int i = 1; i <= m; i++) if (p[i] % 3) ans = 0;
printf("%d", ans);
exit(0);
}
for (int i = 0; i <= p[1]; i += 3) for (int j = 0; j <= p[2]; j += 3) dp[now][p[2] - j][p[1] - i] = 1;
}
signed main()
{
scanf("%d %d", &n, &m);
for (int i = 1, tmp; i <= n; i++) scanf("%d", &tmp), p[tmp]++;
init();
for (int i = 3; i <= m; i++) {
/*初始化*/ for (int j = 0; j <= p[i]; j++) for (int k = 0; k <= p[i - 1]; k++) dp[nxt][j][k] = 0;
for (int j = 0; j <= p[i - 1]; j++) for (int k = 0; k <= std::min(p[i - 2], j); k++) {
for (int q = 0; q <= p[i] && p[i] - q >= k; q += 3) {
addon(dp[nxt][p[i] - q - k][j - k], dp[now][j][k]);
}
}
std::swap(now, nxt);
}
printf("%d", dp[now][0][0]);
return 0;
}
总结#
一类只钦定消除 不消除以后就不能消除的元素 的
一般记录到达 不消除以后就不能消除的元素 之前的元素还剩下多少个来处理
往往一种操作只用一次转移考虑才能做到去重
首先, 一组合法情况可以视作对值域数组
- 对于
, 进行 次操作构造 个 - 对于任意
, 进行 次操作
如果恰好把
因此我们枚举
类似于之前多重集排列那一部分, 这个问题同样可以表述为
求有多少组组
然后稍微转化一下, 把
这也是一种理解
一般适用于这种不常规的
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】