AtCoder Beginner Contest 282 G - Similar Permutation
套路题
题意
求有多少个 \(1\) 到 \(n\) 的排列满足恰有 \(k\) 对在排列中相邻的数满足前小于后
\(2 \leq n \leq 500, 0 \leq k \leq (n - 1)\)
思路
f[i][j][k]
表示已经放置了前 i
个数, 放置的第i
个数是前i
个数中第j
大的($ 1\leq\(`j`\)\leq$i
),已放置的前i
个数形成的所有排列满足恰有 k
对在排列中相邻的数满足前小于后的排列数量。
放置第i+1
个数时,第i+1
个数是前i+1
个数中第j
大的,第i
个数是严格小于前i
个数中第j
大的,会为排列增加一对相邻的数满足前小于后,第i
个数是大于等于前i
个数中第j
大的,不会为排列增加一对相邻的数满足前小于后,转移方程为:
\]
显然,后面的和式可以通过前缀和优化的。
时间复杂度为\(O(n^2k)\)。
G - Similar Permutation
题意
求\(1\)到\(n\)的排列\(A\) 和 \(B\)的相似度为\(k\)的数量。
相似度计算:\(k = \sum_{i = 2}^{n}[(A_i - A_{i-1})(B_i - B_{i-1}) > 0]\) (\([X] = 1, X 为真,[X] = 0, X为假\))。
\(2 \leq n \leq 100, 0 \leq k \leq (n - 1)\)。
思路
与前一道题相比,这一题只是增加了一维状态。
f[i][a][b][k]
表示排列\(A\),\(B\)已经放置了前 i
个数, 排列\(A\)放置的第i
个数在排列\(A\)中是第a
大的,排列\(B\)放置的第i
个数在排列\(B\)中是第b
大的,此时相似度为\(k\)的排列数量。
转移方程为:
\sum_{x = a}^{i}\sum_{y = b}^{i} f_{ixy(k-1)} +
\sum_{x = 1}^{a - 1}\sum_{y = b}^{i} f_{ixyk} +
\sum_{x = a}^{i}\sum_{y = 1}^{b - 1} f_{ixyk}
\]
和式同样可以使用前缀和来优化。
时间复杂度为\(O(n^4)\)。
代码
int pre[107][107][107], f[107][107][107];
void solve_problem() {
int n, m, P;
std::cin >> n >> m >> P;
auto add = [&](int a, int b) -> int {
a += b;
if ( a >= P ) a -= P;
return a;
};
auto sub = [&](int a, int b) -> int {
a -= b;
if ( a < 0 ) a += P;
return a;
};
auto sum = [&](int n, int x1, int y1, int x2, int y2) -> int {
if (n < 0) return 0;
return add(sub(sub(pre[n][x2][y2], pre[n][x2][y1 - 1]), pre[n][x1 - 1][y2]), pre[n][x1 - 1][y1 - 1]);
};
for (int i = 0; i <= n; i++)
for (int j = 0; j <= n; j++)
for (int h = 0; h <= n; h++)
pre[i][j][h] = f[i][j][h] = 0;
f[0][1][1] = 1;
for (int i = 1; i <= n; i++) {
for (int k = 0; k <= i + 1; k++) {
for (int a = 1; a <= i; a++) {
for (int b = 1; b <= i; b++) {
pre[k][a][b] = add(pre[k][a][b - 1], f[k][a][b]);
}
}
for (int b = 1; b <= i; b++) {
for (int a = 1; a <= i; a++) {
pre[k][a][b] = add(pre[k][a][b], pre[k][a - 1][b]);
}
}
}
for (int k = 0; k <= i + 1; k++) {
for (int a = 1; a <= i + 1; a++) {
for (int b = 1; b <= i + 1; b++) {
f[k][a][b] = add(
add(sum(k - 1, 1, 1, a - 1, b - 1), sum(k - 1, a, b, i, i)),
add(sum(k, 1, b, a - 1, i), sum(k, a, 1, i, b - 1))
);
}
}
}
}
std::cout << sum(m, 1, 1, n, n) << "\n";
}
AtCoder Beginner Contest 282 G - Similar Permutation的更多相关文章
- AtCoder Beginner Contest 260 G // imos(累积和算法)
题目传送门:G - Scalene Triangle Area (atcoder.jp) 题意: 给定大小为N*N的OX矩阵,若矩阵的(s,t)处为O,其覆盖范围为:满足以下条件的所有位置(i,j) ...
- AtCoder Beginner Contest 136
AtCoder Beginner Contest 136 题目链接 A - +-x 直接取\(max\)即可. Code #include <bits/stdc++.h> using na ...
- AtCoder Beginner Contest 137 F
AtCoder Beginner Contest 137 F 数论鬼题(虽然不算特别数论) 希望你在浏览这篇题解前已经知道了费马小定理 利用用费马小定理构造函数\(g(x)=(x-i)^{P-1}\) ...
- AtCoder Beginner Contest 076
A - Rating Goal Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Takaha ...
- AtCoder Beginner Contest 075 C bridge【图论求桥】
AtCoder Beginner Contest 075 C bridge 桥就是指图中这样的边,删除它以后整个图不连通.本题就是求桥个数的裸题. dfn[u]指在dfs中搜索到u节点的次序值,low ...
- AtCoder Beginner Contest 154 题解
人生第一场 AtCoder,纪念一下 话说年后的 AtCoder 比赛怎么这么少啊(大雾 AtCoder Beginner Contest 154 题解 A - Remaining Balls We ...
- AtCoder Beginner Contest 177 题解
AtCoder Beginner Contest 177 题解 目录 AtCoder Beginner Contest 177 题解 A - Don't be late B - Substring C ...
- 题解 AtCoder Beginner Contest 168
小兔的话 欢迎大家在评论区留言哦~ AtCoder Beginner Contest 168 A - ∴ (Therefore) B - ... (Triple Dots) C - : (Colon) ...
- AtCoder Beginner Contest 223
AtCoder Beginner Contest 223 A是纯纯的水题,就不说了 B - String Shifting 思路分析 我真的sb,一开始想了好久是不是和全排列有关,然后读了好几遍题目也 ...
- KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解
KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解 哦淦我已经菜到被ABC吊打了. A - Century 首先把当前年 ...
随机推荐
- Debian安装 WineHQ 安装包
https://wiki.winehq.org/Debian_zhcn WineHQ 源仓库的密钥于 2018-12-19 改变过.如果您在此之前下载添加过该密钥,您需要重新下载和添加新的密钥并运行 ...
- ES6 学习笔记(二)解构赋值
一.数组的解构赋值 1.基本用法 ES6允许按照一定模式从数组和对象中提取值,然后对变量进行赋值,该操作即为解构 如: let [a,b,c]=[1,2,3]; console.log(a,b,c) ...
- 如何使用vscode快速配置C语言环境(简单实用)
需要用到的工具: VSCode(Visual Studio Code) 一.首先打开官网链接,然后根据自己的电脑选择合适的安装程序进行下载. 二.在安装时默认点击下一步,最后记得勾选上添加path到系 ...
- xlwings 模块总结
基本使用 在子线程中使用时,有时需要在子线程函数中加入以下.有时不需要加入,目前还不明白具体的原因 import pythoncom # 导入的库 pythoncom.CoInitialize() # ...
- SQL Server 读写分离配置的一些问题
1,新建发布服务器遇到此服务器上未安装复制组件 先执行以下sql use mastergoselect @@servername;select serverproperty('servername') ...
- perl大小写转换函数uc和lc
$side = uc $attrs[0]; #把attrs[0]转换成大写,然后给side变量赋值. $gender = lc $attrs[1]; #把attrs[1]转换成小写,然后给gender ...
- Json web token(JWT)攻防
免责声明: 本文章仅供学习和研究使用,严禁使用该文章内容对互联网其他应用进行非法操作,若将其用于非法目的,所造成的后果由您自行承担,产生的一切风险与本文作者无关,如继续阅读该文章即表明您默认遵守该内容 ...
- bugku web基础$_GET
让我们通过url传入what的值,让其等于flag 直接构造url就得到flag了
- 简单的sql注入2
尝试 1 1' 1" 发现1'还是会报错,所以注入口还是1' 再试试1' and '1'='1发现报出SQLi detected! 取消空格试试1'and'1'='1 似乎可以进入,应该就是 ...
- c++题目:切香肠
c++题目:切香肠 题目 题目描述 有 n 条香肠,每条香肠的长度相等.我们打算将这些香肠切开后全部分给 k 名客人,且要求每名客人获得一样多的香肠.请问最少需要切几刀?注意一刀只能切断一条香肠,每个 ...