排成一条线的纸牌博弈问题

来源:互联网 发布:windows使窗口变灰api 编辑:程序博客网 时间:2024/04/29 04:26
/***************************************************************************
 *description:排成一条线的纸牌博弈问题
 *            给定一个整型数组arr,代表数值不同的纸牌排成一条线
 *            玩家A和玩家B依次拿走每张纸牌,规定A先拿。
 *            每个玩家每次只能拿走最左或最右的纸牌。
 *            返回最后获胜者的分数。
 *            例:arr=[1,2,100,4]
 *                玩家A拿走1,然后B拿走2或4,A再拿100,返回101

 **************************************************************************/

#include<iostream>#include<vector>using namespace std;//方法1:暴力递归。时间复杂度O(2^N),空间复杂度O(N)//定义函数f[i][j]表示arr[i...j]被绝顶聪明的人先拿得到的分数。//              i==j时,就一张牌,直接返回arr[i];否则该人只能拿arr[i]或arr[j]://              拿arr[i],剩下的arr[i+1...j]他变成后拿的人;拿arr[j],剩下的arr[i...j-1]他变成后拿的人;//              所以函数返回max(arr[i]+s[i+1][j], arr[j]+s[i][j-1])//定义函数s[i][j]表示arr[i...j]被绝顶聪明的人后拿得到的分数。//              i==j时,先拿的拿走,后拿的没有,返回0;否则//              先拿的人可能拿走arr[i]或arr[j].由于先拿的也是绝顶聪明//              所以函数返回min(f[i+1][j],f[i][j-1])int f(vector<int> arr, int left, int right);int s(vector<int> arr, int left, int right){    if (left == right)        return 0;    return min(f(arr,left+1,right),f(arr,left,right-1));}int f(vector<int> arr, int left, int right){    if (left == right)        return arr[left];    return max(arr[left]+s(arr,left+1,right), arr[right]+s(arr,left,right-1));}int winerScore_1(vector<int> arr){    if (arr.size() == 0)        return 0;    return max(f(arr, 0, arr.size()-1), s(arr, 0, arr.size()-1));}//方法2:动态规划。时间复杂度O(N^2),空间复杂度O(N^2)int winerScore_2(vector<int> arr){    if (arr.size() == 0)        return 0;    int N = arr.size();    vector<vector<int>> s(N,N);    vector<vector<int>> f(N,N);    f[0][0] = arr[0];    s[0][0] = 0;    for (int i = N-1; i >= 0; i--)    {        f[i][i] = arr[i];        s[i][i] = 0;        for (int j = i+1; j < N; j++)        {            f[i][j] = max(arr[i]+s[i+1][j], arr[j]+s[i][j-1]);            s[i][j] = min(f[i+1][j], f[i][j-1]);        }    }    return max(s[0][N-1], f[0][N-1]);}int main(){    vector<int> arr;    arr.push_back(1);    arr.push_back(2);    arr.push_back(100);    arr.push_back(4);    cout << winerScore_2(arr);}


原创粉丝点击