当前位置:实例文章 » 其他实例» [文章]AtcoderABC249场

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$ 个相同的数字和第

相关标签:算法
其他信息

其他资源

Top