在博弈问题中,极小极大化(Minimax)算法常用于二人零和博弈游戏,目的是寻找最优的方案使得自己能够利益最大化。
该算法的基本思想就是假设自己足够聪明,总是选择最利于自己的方案,而对手同样聪明,总是选择最不利于对方即己方的方案。
此算法会需要根据所有可能的结果生成一个博弈树。
在博弈树中(如下图),从叶子节点出发,当由我方进行选择时,我们总是会选择其儿子节点当中,值最大的那一个,而假定对手总是会选择其儿子节点中,值最小的那一个。决策树中从根节点出发,每一层由我方和对方轮流进行选择
现在给出一次博弈的所有可能的结果(即决策树的叶子节点),请你求解出整棵树的非叶子节点并输出。为简化问题,题目保证对应的博弈树一定是一棵完美二叉树。
输入格式:
输入共两行。
第一行包含一个整数 n ,2≤n≤256。
第二行包含 n 个整数,分别是叶子节点值按层序遍历的结果(从左至右)。
输出格式:
输出包含若干行。
对于第 i 行,输出博弈树对应第 i 层的所有节点值(按层序遍历从左至右),节点值之间用一个空格隔开。
输入样例:
8
2 5 6 7 4 8 9 3
输出样例:
8
5 8
5 7 8 9
#include <bits/stdc++.h>
using namespace std;
int n;
//log2(double) return double
//log10(double) return double
//同一类型不同size的vector 可以相互赋值,完全覆盖
//vector可以用rbegin(),rend()倒序遍历
int main() {
cin >> n;
vector<int> current_level(n);
for (auto& val : current_level) {
cin >> val;
}
const int depth = log2(n);
bool is_max_level = (depth % 2 == 1); // 确定初始先手
vector< vector<int> > decision_tree;
while (current_level.size() > 1) {
vector<int> next_level;
for (size_t i = 0; i < current_level.size(); i += 2) {
int selected = is_max_level ?
max(current_level[i], current_level[i+1]) :
min(current_level[i], current_level[i+1]);
next_level.push_back(selected);
}
decision_tree.push_back(next_level);
current_level = next_level;
is_max_level = !is_max_level; // 更换玩家
}
for (auto it = decision_tree.rbegin(); it != decision_tree.rend(); ++it) {
for (size_t j = 0; j < it->size(); ++j) {
if (j) cout << " ";
cout << (*it)[j];
}
cout << endl;
}
return 0;
}