Predict the winner
来源:互联网 发布:淘宝怎样免费开店 编辑:程序博客网 时间:2024/06/05 20:53
1 问题描述
Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from either end of the array followed by the player 2 and then player 1 and so on. Each time a player picks a number, that number will not be available for the next player. This continues until all the scores have been chosen. The player with the maximum score wins.
Given an array of scores, predict whether player 1 is the winner. You can assume each player plays to maximize his score.
2例子说明
Example 1:
Input: [1, 5, 2]
Output: False
Explanation: Initially, player 1 can choose between 1 and 2.
If he chooses 2 (or 1), then player 2 can choose from 1 (or 2) and 5. If player 2 chooses 5, then player 1 will be left with 1 (or 2).
So, final score of player 1 is 1 + 2 = 3, and player 2 is 5.
Hence, player 1 will never be the winner and you need to return False.
Example 2:
Input: [1, 5, 233, 7]
Output: True
Explanation: Player 1 first chooses 1. Then player 2 have to choose between 5 and 7. No matter which number player 2 choose, player 1 can choose 233.
Finally, player 1 has more score (234) than player 2 (12), so you need to return True representing player1 can win.
3解决思路
使用动态规划(DP)来解决这个问题。思路:
题目的要求等价于第一个玩家最后选择的分数之和能否达到全部分数之和的一半以上。
DP(i,j)表示某个player需要在原序列第i个元素到第j个元素这个序列所能选择到的最多分数。Sum(i,j)表示第i个元素到第j个元素分数之和。Nums表示原序列。
在DP(i,j)时刻该玩家只能选择第i个和第j个元素。
如果选择第i个元素,那么该玩家将获得分数:
DPL(i,j)=Nums[i]+Sum(i,j)-DP(i+1,j)
如果选择第j个元素,那么该玩家将获得分数:
DPR(i,j)=Nums[j]+Sum(i,j)-DP(i,j-1)
因此该玩家会选择使得DP(i,j)更大那个元素。因此有
DP(i,j)=max{DPL,DPR}。
4 代码实现
#include "stdafx.h"#include<vector>#include<iostream>#include<algorithm>using namespace std;bool solution(const vector<int> & nums){ vector<vector<int>> score(nums.size(), vector<int>(nums.size())); vector<int> preSums(nums.size() + 1); preSums[0] = 0; for (unsigned int i = 1; i < preSums.size(); i++) { preSums[i] = preSums[i - 1] + nums[i - 1]; } for (int unsigned len = 1; len <= nums.size(); len++){ for (int unsigned lhs = 0; lhs + len - 1 < nums.size(); lhs++){ int rhs = lhs + len - 1; if (rhs == lhs){ score[lhs][rhs] = nums[rhs]; } else if (lhs == rhs - 1){ score[lhs][rhs] = max(nums[lhs],nums[rhs]); } else { int leftscore = nums[lhs] + preSums[rhs + 1] - preSums[lhs + 1] - score[lhs + 1][rhs]; int rightscore = nums[rhs] + preSums[rhs] - preSums[lhs] - score[lhs][rhs - 1]; score[lhs][rhs] = max(leftscore, rightscore); } } } return score[0][nums.size() - 1] >= preSums[nums.size()] / 2 + preSums[nums.size()] % 2;}int _tmain(int argc, _TCHAR* argv[]){ vector<int> iv; iv.reserve(50); int i; while(cin>>i){ iv.push_back(i); } if (solution(iv)){ cout << "True" << endl; } else cout << "False" << endl; return 0;}
5总结
该算法的时间复杂度为O(n*n)。DP思想在这里体现为维护一个矩阵,将大规模的问题转化为比它小的已经解决的问题。这跟斐波那契数列使用一个数组来记录已经解决的值得思想类似。此问题应该也可以使用递归方法解决,复杂度可能会更高。
- 486. Predict the Winner**
- 486. Predict the Winner
- 486. Predict the Winner
- Predict the winner
- 486. Predict the Winner
- Predict the Winner
- Predict the Winner
- Predict the Winner
- 486. Predict the Winner
- Predict the Winner
- 【486】 Predict the Winner
- 486. Predict the Winner
- Predict the Winner
- 486. Predict the Winner
- LeetCode12 Predict the Winner
- 486. Predict the Winner
- 486. Predict the Winner
- [leetcode] predict the winner
- 聊聊Linux操作系统对进程的调度
- 员工管理系统之MYSQL
- java中Scanner类nextInt之后用nextLine无法读取输入
- 2016蓝桥杯javaA组第五题答案
- HBase 理解
- Predict the winner
- 时域和频域之间联系
- 【九度OJ】题目1065:输出梯形 解题报告
- 《Android高级进阶》目录
- N皇后问题的非递归回溯和递归回溯
- 主元消去法(N元一次方程组)
- Leetcode 491. Increasing Subsequences 上升序列 解题报告
- Spring编程式事务管理和声明式事务管理 案例
- Java虚拟机运行时数据区域