BJTU 1688 Quartz的宝藏

传送门:http://acm.bjtu.edu.cn/problem/detail?pid=1688

解题思路:与字符串字典序问题相似,不过本题的要求更为复杂,最初以为可以用贪心解决,不过很显然没这么简单,首先要考虑两边的数字相同的情况,但是同时你又要考虑内部的大小关系,不能让对方拿到过大的金子,一度思维进入僵局,可见当时对于dp还不是很熟悉,而本题明显需要一种动态规划的思想。

解题方法:DP + 前缀和

代码如下:
#include <iostream>
#include <cstdio>
using namespace std;

int sum[505];   //保存前缀和
int a[505];     //save the gold
int dp[505][505];
int main()
{
    freopen("test.txt","r",stdin);
    int t,i,j;
    int l,r;
    int total;
    int n;
    scanf("%d",&t);
    for(i=1;i<=t;i++)
    {
        scanf("%d",&n);
        total = 0;
        for(j=1;j<=n;j++)
        {
            scanf("%d",&a[j]);
            total += a[j];
            sum[j] = total;     //记录前缀和
            dp[j][j] = a[j];
        }
        for(l=n;l>0;l--)
        {
            for(r=l+1;r<=n;r++)
            {
                int temp1,temp2;    				//分别模拟从两边取出数字的情况
                temp1 = a[l] + sum[r] - sum[l] - dp[l+1][r];
                temp2 = a[r] + sum[r-1] - sum[l-1] - dp[l][r-1];//dp【l】【r】认为是从l开始到r由此人来取最后一个数的时候,他能获得的最大数值
                dp[l][r] = max(temp1,temp2);
            }
        }
        printf("Case #%d: ",i);
        printf("%d %d\n",dp[1][n],total-dp[1][n]);
    }
    //cout << "Hello world!" << endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值