#include <iostream>
#include <vector>
#include<string>
#include<algorithm>
using namespace std;
int post_min(int *arr, int l, int r);
int pre_max(int *arr, int l, int r);
int pre_max(int *arr, int l, int r) { // 先选肯定是使自己获得最大值,在后选的两个中选最大的
if (l == r) return arr[l]; // 递归的终止条件
return max(post_min(arr, l + 1, r) + arr[l], post_min(arr, l, r - 1) + arr[r]);
}
int post_min(int *arr, int l, int r) { // 后选获得的对手让你得到最小值,在先选的两个中最小的
if (l == r) return 0;
return min(pre_max(arr, l + 1, r), pre_max(arr, l, r - 1)); // 注意这里是最小不是最大
}
int findMax(int *arr, int n) {
return max(pre_max(arr, 0, n - 1), post_min(arr, 0, n - 1)); // 先选和后选中的最大值
}
int findMax1(vector<int> &num) {
if (num.empty()) return 0;
int len = num.size();
vector<vector<int>> first_pick(len,vector<int>(len,0));
vector<vector<int>> second_pick(len, vector<int>(len, 0));
for (int j = 0; j < len; j++) {
first_pick[j][j] = num[j];
for (int i = j - 1; i >= 0; i--) {
first_pick[i][j] = max(num[i] + second_pick[i + 1][j], num[j] + second_pick[i][j - 1]);
second_pick[i][j] = min(first_pick[i + 1][j], first_pick[i][j - 1]);
}
}
return max(first_pick[0][len - 1], second_pick[0][len - 1]);
}
int main() {
int arr[] = { 1, 2, 100, 4 };
cout << findMax(arr, 4) << endl;
vector<int>num = { 1, 2, 100, 4 };
cout << findMax1(num) << endl;
}
排成一条线的纸牌博弈问题
最新推荐文章于 2023-03-05 20:09:44 发布