Coins In A Line 3

Solution

[3, 2, 3]

一个区间的硬币,A和B互相抽取,每次只能抽取一个,可以从左边或者右边抽,问A先手能否胜利?

因为可以从两边抽,原先的一维DP已经无法满足,所以引出了二维空间DP的概念。

和其他DP一样,状态方程是最重要的。

dp[i][j] = sum[i][j] - min(dp[i+1][j], dp[i][j-1])

min里面的意思是,让后手的B取的尽量少,这样A在这一轮就尽量多!!!

code

class Solution { public: /**

 * @param values: a vector of integers
 * @return: a boolean which equals to true if the first player will win
 */
bool firstWillWin(vector<int> &values) {
    // write your code here
    if(values.size() == 0)
    {
        return false;
    }

    int n = values.size();

    vector<vector<int>> dp;
    vector<vector<bool>> flag;
    vector<vector<int>> sum;
    for(int i = 0; i<n; i++)
    {
        vector<int> tmp(n, 0);
        tmp[i] = values[i];
        vector<bool> tmp2(n, false);
        dp.push_back(tmp);
        sum.push_back(tmp);
        flag.push_back(tmp2);
    }

    for(int i = n-1; i >= 0; i--)
    {
        for(int j = i+1; j<n; j++)
        {
            sum[i][j] = sum[i][j-1] + sum[j][j];
        }
    }
    /*
    for(int i = n-1; i >= 0; i--)
    {
        for(int j = i+1; j<n; j++)
        {
            dp[i][j] = sum[i][j] - min(dp[i+1][j], dp[i][j-1]);
        }
    }

    return dp[0][n-1] * 2 > sum[0][n-1];*/

    return memSearch(dp, flag, sum, 0, n-1)*2>sum[0][n-1];

}

int memSearch(vector<vector<int>>& dp, vector<vector<bool>>& flag, vector<vector<int>>& sum, int i, int j)
{

    if(flag[i][j])
    {
        return dp[i][j];
    }

    if(i > j)
    {
        return 0;
    }

    if(i == j)
    {
        return dp[i][i];
    }

    dp[i][j] = sum[i][j] - min(memSearch(dp, flag, sum ,i+1, j), memSearch(dp, flag, sum, i, j-1));

    flag[i][j] = true;

    return dp[i][j];
}

};

results matching ""

    No results matching ""