AtcoderABC249场
发布人:shili8
发布时间:2025-01-24 20:31
阅读次数:0
**AtCoder ABC249**
### **D.**
#### **Problem:**
在一个 $n times n$ 的棋盘上,放置了 $m$ 个皇后。每个皇后都有一个唯一的颜色(红、蓝或绿)。现在,我们想将这些皇后排列成一行,使得每对皇后之间的距离尽可能大。
#### **Constraints:**
* $1 le n le8$
* $n le m le56$
* 每个皇后的颜色都是唯一的#### **Solution:**
我们首先考虑一下,如果有两个皇后在同一行上,那么它们之间的距离就是0。因此,我们可以将每对皇后之间的距离视为一个矩阵 $d$,其中 $d_{ij}$ 表示第 $i$ 个皇后的颜色和第 $j$ 个皇后的颜色相同的皇后的数量。
我们需要找到一个排列,使得对于所有 $i
eq j$,$d_{ii} - d_{ij} +1$ 的最大值尽可能大。由于 $n le m le56$,因此我们可以将这个问题转化为一个二维数组的最大子矩阵和问题。
#### **Code:**
cpp#include <iostream> #include <vector> using namespace std; const int N =8; const int M =56; int n, m; int d[N +1][N +1]; int ans =0; void dfs(int x, int y) { if (x == m +1) { for (int i =1; i <= m; ++i) for (int j =1; j <= m; ++j) d[i][j] =0; for (int i =1; i <= n; ++i) for (int j =1; j <= n; ++j) { int cnt =0; for (int k =1; k <= m; ++k) if ((x != k && y != k && d[x][k] == d[y][k]) || x == k || y == k) ++cnt; ans = max(ans, n - cnt); } return; } for (int i =1; i <= m; ++i) { if (x != i && y != i && d[x][i] == d[y][i]) continue; d[x][y] = d[y][x] = d[x][i] +1; dfs(x, i); d[x][y] = d[y][x] = d[i][y] = d[x][i]; } } int main() { cin >> n >> m; dfs(0,0); cout << ans << endl; return0; }
### **E.**
#### **Problem:**
给定一个长度为 $n$ 的序列,序列中有 $k$ 个相同的数字。现在,我们想将这个序列分成尽可能多的子序列,使得每个子序列都是递增的。
#### **Constraints:**
* $1 le n le2 cdot10^5$
* $0 le k le n$
#### **Solution:**
我们首先考虑一下,如果有两个相同的数字,那么它们之间的距离就是0。因此,我们可以将每对相同的数字之间的距离视为一个矩阵 $d$,其中 $d_{ij}$ 表示第 $i$ 个相同的数字和第 $j$ 个相同的数字之间的距离。
我们需要找到一个分割,使得对于所有 $i
eq j$,$d_{ii} - d_{ij} +1$ 的最大值尽可能大。由于 $n le2 cdot10^5$,因此我们可以将这个问题转化为一个二维数组的最大子矩阵和问题。
#### **Code:**
cpp#include <iostream> #include <vector> using namespace std; const int N =200000; int n, k; int d[N +1][N +1]; int ans =0; void dfs(int x, int y) { if (x == k +1) { for (int i =1; i <= k; ++i) for (int j =1; j <= k; ++j) d[i][j] =0; for (int i =1; i <= n; ++i) for (int j =1; j <= n; ++j) { int cnt =0; for (int p =1; p <= k; ++p) if ((x != p && y != p && d[x][p] == d[y][p]) || x == p || y == p) ++cnt; ans = max(ans, n - cnt); } return; } for (int i =1; i <= k; ++i) { if (x != i && y != i && d[x][i] == d[y][i]) continue; d[x][y] = d[y][x] = d[x][i] +1; dfs(x, i); d[x][y] = d[y][x] = d[i][y] = d[x][i]; } } int main() { cin >> n >> k; dfs(0,0); cout << ans << endl; return0; }
### **F.**
#### **Problem:**
给定一个长度为 $n$ 的序列,序列中有 $k$ 个相同的数字。现在,我们想将这个序列分成尽可能多的子序列,使得每个子序列都是递减的。
#### **Constraints:**
* $1 le n le2 cdot10^5$
* $0 le k le n$
#### **Solution:**
我们首先考虑一下,如果有两个相同的数字,那么它们之间的距离就是0。因此,我们可以将每对相同的数字之间的距离视为一个矩阵 $d$,其中 $d_{ij}$ 表示第 $i$ 个相同的数字和第 $j$ 个相同的数字之间的距离。
我们需要找到一个分割,使得对于所有 $i
eq j$,$d_{ii} - d_{ij} +1$ 的最大值尽可能大。由于 $n le2 cdot10^5$,因此我们可以将这个问题转化为一个二维数组的最大子矩阵和问题。
#### **Code:**
cpp#include <iostream> #include <vector> using namespace std; const int N =200000; int n, k; int d[N +1][N +1]; int ans =0; void dfs(int x, int y) { if (x == k +1) { for (int i =1; i <= k; ++i) for (int j =1; j <= k; ++j) d[i][j] =0; for (int i =1; i <= n; ++i) for (int j =1; j <= n; ++j) { int cnt =0; for (int p =1; p <= k; ++p) if ((x != p && y != p && d[x][p] == d[y][p]) || x == p || y == p) ++cnt; ans = max(ans, n - cnt); } return; } for (int i =1; i <= k; ++i) { if (x != i && y != i && d[x][i] == d[y][i]) continue; d[x][y] = d[y][x] = d[x][i] +1; dfs(x, i); d[x][y] = d[y][x] = d[i][y] = d[x][i]; } } int main() { cin >> n >> k; dfs(0,0); cout << ans << endl; return0; }
### **G.**
#### **Problem:**
给定一个长度为 $n$ 的序列,序列中有 $k$ 个相同的数字。现在,我们想将这个序列分成尽可能多的子序列,使得每个子序列都是递增的。
#### **Constraints:**
* $1 le n le2 cdot10^5$
* $0 le k le n$
#### **Solution:**
我们首先考虑一下,如果有两个相同的数字,那么它们之间的距离就是0。因此,我们可以将每对相同的数字之间的距离视为一个矩阵 $d$,其中 $d_{ij}$ 表示第 $i$ 个相同的数字和第