关闭

Codevs 3196 黄金宝藏

标签: 区间dp
121人阅读 评论(0) 收藏 举报
分类:
P3196 黄金宝藏

描述

小毛终于到达宝藏点,他意外地发现有一个外星人(名叫Pluto)。宝藏是一些太空黄金,有n堆排成一行,每堆中有xi颗黄金。小毛和Pluto决定轮流从中取出黄金,规则是每次只能从最左边或最右边取出一堆黄金,直到所有黄金被取出。小毛先取,两人都以最优策略进行选取,求两人的最后所得。

格式

输入格式

第一行是正数n(≤500);第二行为n个正整数xi(≤300),表示每堆黄金的个数。

输出格式

仅两个整数,分别表示小毛和Pluto的得分,以空格隔开。

样例1

样例输入1[复制]

6 
4 7 2 9 5 2
				

样例输出1[复制]

18 11
				

限制

每个测试点1s

来源

Codevs 3196

记:dp[i][j]为先手在[i,j]区间内所能得到的最大值,由于只能去最左边的和最右边的,那么
如果某人取了最左边的: dp[i][j] = max(dp[i][j],a[i] + sum[j] - sum[i] - dp[i + 1][j]);
如果某人取了最右边的: dp[i][j] = max(dp[i][j],a[j] + sum[j - 1] - sum[i - 1] - dp[i][j - 1]);
不管是取了最左边的还是最右边的,第一个人取之后轮到另一个人取,那么另一个人为先手,那么dp[i + 1][j]或者dp[i][j - 1]为另一个人在区间内所能得到的最大值,那么第一个人的为sum - dp

代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define pi acos(-1.0)
#define maxn (500 + 50)
#define mol 1000000007
#define inf 0x3f3f3f3f
#define Lowbit(x) (x & (-x))
using namespace std;
typedef long long int LLI;

int a[maxn],sum[maxn],tot = 0;
int dp[maxn][maxn];

int main() {
    int n;
    scanf("%d",&n);
    sum[0] = 0;
    for(int i = 1; i <= n; i ++)  {
        scanf("%d",&a[i]);
        tot += a[i];
        sum[i] = sum[i - 1] + a[i];
    }
    for(int len = 1;len <= n;len ++){
        for(int i = 1;i + len - 1 <= n;i ++){
            int j = i + len - 1;
            dp[i][j] = max(dp[i][j],a[i] + sum[j] - sum[i] - dp[i + 1][j]);
            dp[i][j] = max(dp[i][j],a[j] + sum[j - 1] - sum[i - 1] - dp[i][j - 1]);
        }
    }
    printf("%d %d\n",dp[1][n],tot - dp[1][n]);
    return 0;
}

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:15810次
    • 积分:882
    • 等级:
    • 排名:千里之外
    • 原创:74篇
    • 转载:7篇
    • 译文:0篇
    • 评论:12条
    文章分类
    最新评论