前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >天池 在线编程 双向取数(博弈DP)

天池 在线编程 双向取数(博弈DP)

作者头像
Michael阿明
发布2021-02-19 14:33:48
3540
发布2021-02-19 14:33:48
举报
文章被收录于专栏:Michael阿明学习之路

1. 题目

有一个长度为n的数列arr, 甲乙两个人每次可以从头或者从末尾取一个数,双方都想让自己取数之和尽量多,

甲先取数,问甲乙在采取最优策略的基础下,甲最多得多少分?

代码语言:javascript
复制
n<=800

示例
给定arr=[8,6,9,4,4,3],返回21
给定arr=[1,3,5,8,7,9,1],返回14

2. 解题

相关题目:LeetCode 博弈DP系列

  • dp[i][j] 表示 剩下的数字的区间为 [i,j] 时,先手的最大分差,使用区间DP求取
  • 假设 两人的最佳得分为 a(先手), b, 有 a + b = s u m , a − b = d p 0 a+b = sum, a-b = dp0 a+b=sum,a−b=dp0,解方程即得到 a
代码语言:javascript
复制
class Solution {
public:
    /**
     * @param arr: the number array
     * @return: output the maximal score Alice can get
     */
    int getAns(vector<int> &arr) {
        // Write your code here
        int n = arr.size();
        int sum = accumulate(arr.begin(), arr.end(), 0);//总的分数
        vector<vector<int>> dp(n, vector<int>(n, 0));
        for(int i = 0; i < n; i++) 
            dp[i][i] = arr[i];//只剩一个数字时的得分
        for(int len = 1; len <= n; len++)
        {
            for(int i = 0; i+len < n; i++)
            {
                int j = i+len;
                dp[i][j] = max(-dp[i+1][j]+arr[i], -dp[i][j-1]+arr[j]);
                //         上一个人的分差取负就是我的分差,加上我的得分,两种选择取大的
            }
        }
        return (sum+dp[0][n-1])/2;
    }
};

50ms C++

我的CSDN博客地址 https://michael.blog.csdn.net/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/01/01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 题目
  • 2. 解题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档