[LeetCode] 486、予測勝者

タイトル説明

指定された配列は、非負の整数の分数を表します。2人のプレーヤーに続いて分画の配列のいずれかの末端からプレイヤーを選択、アレイの両端からの残りの部分をピックアップし、その後、遊技者を取るし続ける....... プレイヤーは一部のみを拾うことができますたびに、画分は、もはや後に拾うことをお勧めしません。望ましいいかなる残りの部分がなくなるまでゲームが終了したとき。最終的に得点の勝利の合計までの選手。

プレイヤーが勝者となりますかどうかを予測するスコアを表す配列を考えます。あなたは、各プレイヤーは自分のスコアを最大化するために再生されると仮定することができます。

输入: [1, 5, 233, 7]
输出: True
解释: 玩家1一开始选择1。然后玩家2必须从57中进行选择。无论玩家2选择了哪个,玩家1都可以选择233
最终,玩家1234分)比玩家212分)获得更多的分数,所以返回 True,表示玩家1可以成为赢家。

問題解決のためのアイデア

パズルパズルは、すべての後に、本当の問題は確かに日和見アルゴリズムがそれを行うことができなくなります。

  • 最初のアイデアは、「貪欲」である:常に最大を得るが、これは以下のような仕事、ない[1, 5, 233, 7]テストケースを。
  • ダイナミックプログラミング:一般的に利用可能であるこの種の問題「二人は最終的に、勝つスマートに十分な、あるとし、」ダイナミックプログラミング解決するためのアルゴリズムを。
    • dp[i][j]表現nums[i]nums[j]、両側がスマートに十分であると仮定し、彼らが終了したとき、他のプレイヤー上に上部手とよりは、最大のスコアを取得するためにどのくらいのイエスを。
    • 以下のためにdp[i][j]あなたは、上の手を取った場合、nums[i]は、より上位の手以外のプレイヤーはdp[i+1][j]dp[i][j] = nums[i]-dp[i+1][j]場合は、上部のかかった手を、 nums[j]上側の手よりも、別のプレーヤーdp[i][j-1]dp[i][j] = nums[j]-dp[i][j-1]要約するとdp[i][j] = Math.max(nums[i]-dp[i+1][j], nums[j]-dp[i][j-1])アップ:
    • 初期化:ときi=j、上側の手を勝つために、特定の、そして他のプレイヤーよりも多くの時間、dp[i][j] = nums[i]
    • 戻り値:最後のリターンはdp[0][nums.length-1]ゼロであることができるよりも大きいです。

参照コード

class Solution {
public:
    bool PredictTheWinner(vector<int>& nums) {
        int length = nums.size();
        if(length <= 1)
            return true;
        
        vector<vector<int> > dp(length, vector<int>(length, 0));
        for(int i = 0; i < length; i++)
            dp[i][i] = nums[i];
        for(int i = length-2; i >= 0; i--){  // dp的遍历方向,根据状态转移方程 画画图就能确定
            for(int j = i+1; j < length; j++){
                dp[i][j] = max(nums[i] - dp[i+1][j], nums[j] - dp[i][j-1]);
            }
        }
        
        return dp[0][length-1] >= 0;
    }
};
415元記事公開 ウォンの賞賛603 ビュー150,000 +を

おすすめ

転載: blog.csdn.net/ft_sunshine/article/details/104056774