#刷题总结5

来源:互联网 发布:有关网络暴力的名言 编辑:程序博客网 时间:2024/06/05 09:34

#486. Predict the Winner
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.
一个数组,从左或者右取一个数,最后看谁大,用动态规划的方法
dp[i][j] means the max value we can get if it it’s our turn and only coins between i and j remain。
那么到dp[i] [j]就有4种情况
取i nums[i]+dp[i+1][j-1]or dp[i+2][j-1] 我们取到这两种情况中较小的一种,因为对手也是取最大的情况。
取j nums[j]+dp[i+1][j-1]or dp[i][j-2] ,同上
最后我们在取i,和取j的两种情况中找到最大的既是我们的答案
bool PredictTheWinner(vector& nums) {
int n=nums.size();
vector< vector> dp(n,vector(n,-1));
int mybest=helper(dp,nums, 0, n-1);
return 2*mybest>=accumulate(nums.begin(),nums.end(),0);

}int helper(vector< vector<int>>& dp, vector<int>& nums, int i, int j){    if(i==j) return nums[i];    if(dp[i][j]!=-1) return dp[i][j];    if(i>j) return 0;    if(j==(i+1)) return max(nums[i],nums[j]);    int a=nums[i]+min(helper(dp,nums,i+1,j-1), helper(dp,nums,i+2,j));    int b=nums[j]+min(helper(dp,nums,i+1,j-1),helper(dp,nums,i,j-2));    dp[i][j]=max(a,b);    return max(a,b);}

#494. Target Sum
You are given a list of non-negative integers, a1, a2, …, an, and a target, S. Now you have 2 symbols + and -. For each integer, you should choose one from + and - as its new symbol.
当然这道题可以完全就是搜索,可以得到每一个结果。
但是可以从题目表述中得到Sum不超过1000. 所以我们是可以通过DP来做的。
Given nums = [1, 2, 3, 4, 5] and target = 3 then one possible solution is +1-2+3-4+5 = 3
Here positive subset is P = [1, 3, 5] and negative subset is N = [2, 4]

Then let’s see how this can be converted to a subset sum problem:

              sum(P) - sum(N) = target

sum(P) + sum(N) + sum(P) - sum(N) = target + sum(P) + sum(N)
2 * sum(P) = target + sum(nums)
So the original problem has been converted to a subset sum problem as follows:
Find a subset P of nums such that sum(P) = (target + sum(nums)) / 2

就是找到其中一些和,加起来等于sum(P) = (target + sum(nums)) / 2
所以变成一个n*S的问题
int findTargetSumWays(vector& nums, int s) {
int sum = accumulate(nums.begin(), nums.end(), 0);
return sum < s || (s + sum) & 1 ? 0 : subsetSum(nums, (s + sum) >> 1);
}

int subsetSum(vector<int>& nums, int s) {    int dp[s + 1] = { 0 };    dp[0] = 1;    for (int n : nums)        for (int i = s; i >= n; i--)            dp[i] += dp[i - n];    return dp[s];}
0 0