hdu 5623 KK's Number

36 篇文章 0 订阅
3 篇文章 0 订阅

传送门:
http://acm.hdu.edu.cn/showproblem.php?pid=5623

shit这道题目居然是原题
BZOJ 2091 Poi2010 The Minima Game 动态规划
当时比赛怎么就没注意一下呢,不然又可以多对一道题目了!!
不过这种策略性的dp倒也是第一次见,也想了一段时间才懂这种策略
题目大意:给定n 个数,两个人轮流取,每次可以取走任意一些数,获得的分值是这些数中的最小值
两个人都想让自己的分值-对方的分值最大,求最终先手得分-后手得分

显然每个人取走的都是当前剩下的数中最大的一些数 
 那么考虑倒着做,令f i  表示剩余最小的i 个数时先手-后手的最大差值 
 那么有DP方程f i =max{a j+1 −f j }(0j<i)  
维护个最大值就行了
为什么是减呢,因为每个人都是使用的最优策略,我们姑且可以这样看,上一次取完,对这一次取得是不利的,可以看做是先手后手是轮流与换的,因此是要减的!!维护一个最大值就ok了!!!
#include <cstdio>
#include <algorithm>

using namespace std;

long long dp[50010];
int a[50010];

int main()
{
    int T;
    scanf("%d", &T);
    while (T--)
    {
        int N;
        scanf("%d", &N);
        for (int i = 0; i < N; ++i)
            scanf("%d", &a[i]);
        sort(a, a + N);
        dp[0] = 0;
        long long mx = -1e18;
        for (int i = 0; i < N; ++i)
        {
            mx = max(mx, a[i] - dp[i]);
            dp[i + 1] = mx;
        }
        printf("%I64d\n", dp[N]);
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值