hihocoder-#1338 : A Game

来源:互联网 发布:毕向东java教程视频 编辑:程序博客网 时间:2024/04/29 18:39

http://hihocoder.com/problemset/problem/1338?sid=827401

#1338 : A Game

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

Little Hi and Little Ho are playing a game. There is an integer array in front of them. They take turns (Little Ho goes first) to select a number from either the beginning or the end of the array. The number will be added to the selecter's score and then be removed from the array.

Given the array what is the maximum score Little Ho can get? Note that Little Hi is smart and he always uses the optimal strategy. 

输入

The first line contains an integer N denoting the length of the array. (1 ≤ N ≤ 1000)

The second line contains N integers A1A2, ... AN, denoting the array. (-1000 ≤ Ai ≤ 1000)

输出

Output the maximum score Little Ho can get.

样例输入
4-1 0 100 2
样例输出
99

分析:

显然这是一道动态规划的问题

假设输入为nums=-1 0 100 2 5 3

变量定义:设先取者获得max为first,后取者为sec。再有从左到右的和为sumL,显然sec=sumL-first

按照常规dp问题,从左到右遍历。假设已经到5:

5可以选择取或不取,

如果取5:则下家就会采用最优方案获得左边列(-1 0 100 2)中的first,即上一次first值,首家只能获得上一次sec值

如果不取5:则只能取nums[0],下家就会采用最优方案获得右边列(0 100 2 5)中的first,这时候定义从右到左先取获得max为high,后取者存放在dp数组中

现在考虑dp数组的计算.

目标计算(0 100 2 5)中的0处的dp值:dp[1]

上一次计算(0 100 2)时dp的取值是[0 100 2 0],dp[0]=0不需要使用,dp[1]=100

dp是从外层循环i处倒叙计算,内测循环为j

当j==i时,dp[j]=0

当j==i-1时,dp=min(nums[i], nums[j])

其它情况

如j=2,nums[j]=100

high=max(nums[j] + dp[j + 1], nums[i] + dp[j]);

nums[j] + dp[j + 1]:取当前数100和(2 5)中的dp:dp[j+1]

nums[i] + dp[j]:取最后一个数nums[i]和上一次(100 2 5)的dp:dp[j](同一位置)

更新dp[j]=sumR-high,sumR表示从右到左的和

因此写出如下代码

#include <iostream>#include <vector>#include <algorithm>using namespace std;int main(){int n;cin >> n;vector<int> nums(n);for (int i = 0; i < n; i++)cin >> nums[i];if (n == 1){cout << nums[0] << endl;return 0;}vector<int> dp(n,0);int sumR, sumL = nums[0] + nums[1], first = max(nums[0], nums[1]), sec = sumL - first;for (int i = 2; i < n; i++){sumL += nums[i];sumR = 0;for (int j = i; j > 0; j--){sumR += nums[j];if (j == i)dp[j] = 0;else if (j == i - 1)dp[j] = min(nums[i], nums[j]);elsedp[j] = sumR - max(nums[j] + dp[j + 1], nums[i] + dp[j]);}first = max(nums[i] + sec, nums[0] + dp[1]);sec = sumL - first;}cout << first << endl;return 0;}



0 0
原创粉丝点击