You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
## [【$AcWing$ $444$. 三国游戏】](https://www.acwing.com/problem/content/446/)
|
|
|
|
|
|
|
|
|
|
### 解析
|
|
|
|
|
对于每一个小涵选的武将来说,他的默契值最高的武将会被选走,而这里我们的答案为每个武将搭配默契值次于最大的默契值(每个武将搭配的次大值),通过一个证明,小涵必胜。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
我们取一点$A$,计算机必然会取与$A$点最佳搭配的一点,设为$B$。而此时我们即可取与$A$点第二佳搭配的点$C$。接下来我们就要证明:
|
|
|
|
|
|
|
|
|
|
- 双方均不可能取到最佳搭配
|
|
|
|
|
- 小涵取的必定是最佳方案
|
|
|
|
|
|
|
|
|
|
**证明**:
|
|
|
|
|
先对第一点进行证明:当计算机取某点$D$时,由于计算机的选将策略,点$D$的最佳搭配点已经先一步被我们取了,故计算机不可能取到最佳搭配。而我们也不可能取到最佳搭配,因为当我们取一对最佳搭配中的一点时,还是由于计算机的选将策略,计算机必定会取最佳搭配中的另一点。综上所述,双方均不可能取到最佳搭配。
|
|
|
|
|
|
|
|
|
|
第二点的证明:由上文说到,双方均不可能取到最佳搭配。所以在最开始取时,我们可以取 每个点的次大值的最大值对应的点,即点$A$,待计算机取掉$A$点的最佳搭配点$B$点时,我们即可取$A$点的 **次佳搭配点**,也就是 **所有次佳搭配中的最大值**,又由于最佳搭配无法取到,所以我们取的就是最佳方案,这也是此题正解算法的由来。
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
### $Code$
|
|
|
|
|
```cpp {.line-numbers}
|
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
const int N = 510;
|
|
|
|
|
|
|
|
|
|
int n;
|
|
|
|
|
int w[N][N];
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
cin >> n;
|
|
|
|
|
for (int i = 0; i < n; i++)
|
|
|
|
|
for (int j = i + 1; j < n; j++) {
|
|
|
|
|
cin >> w[i][j];
|
|
|
|
|
w[j][i] = w[i][j];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int res = 0;
|
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
|
|
int x = 0, y = 0; // 最大值,次大值
|
|
|
|
|
for (int j = 0; j < n; j++)
|
|
|
|
|
if (w[i][j] > x) // 更新最大值
|
|
|
|
|
y = x, x = w[i][j]; // 旧的最大值退化为次大值
|
|
|
|
|
else
|
|
|
|
|
y = max(y, w[i][j]); // 可能更新次大值
|
|
|
|
|
res = max(res, y); // 每一行的次大值,放在一起PK出最大值
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 全都必胜
|
|
|
|
|
cout << 1 << endl;
|
|
|
|
|
cout << res << endl;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
```
|