P1430 序列取数

题目描述

给定一个长为\(n\)的整数序列\((n<=1000)\),由\(A\)和\(B\)轮流取数(\(A\)先取)。每个人可从序列的左端或右端取若干个数(至少一个),但不能两端都取。所有数都被取走后,两人分别统计所取数的和作为各自的得分。假设\(A\)和\(B\)都足够聪明,都使自己得分尽量高,求\(A\)的最终得分。

输入输出格式

输入格式:

第一行,一个正整数\(T\),表示有\(T\)组数据。\((T<=100)\)

接着\(T\)行,每行第一个数为\(n\),接着\(n\)个整数表示给定的序列.

输出格式:

输出\(T\)行,每行一个整数,表示\(A\)的得分


看到足够聪明,我下意识以为是博弈论。。

但是似乎并不是,而且我想不出来怎么做。


对于取剩下的子序列\([i,j]\),先手有一个可求的最大得分值。

令\(dp[i][j]\)为子序列\([i,j]\)时,先手取可得的最大分数。

\(dp[i][j]=max(sum[i][j],sum[i][j]-min\{dp[i+k_1][j],dp[i][j-k_2],k_1\in[1,j-i],k_2\in[1,j-i]\})\)

分别对应先手者(于此步的)选全部,选左边的一段选右边的一段三种情况。

我们发现这是三维的,需要枚举\(k\)。

优化?

拿\(l[i][j]\)维护\(min\{dp[i+k_1][j],k_1\in[1,j-i]\}\)

拿\(r[i][j]\)维护\(min\{dp[i][j-k_2],k_2\in[1,j-i]\}\)

当然,这两个东西的更新都是\(O(1)\)的

细节:注意区间DP的枚举顺序性


code:

#include <cstdio>
#include <cstring>
const int N=1010;
int max(int x,int y) {return x>y?x:y;}
int min(int x,int y) {return x>y?y:x;}
int n,t;
int a[N],f[N],dp[N][N],l[N][N],r[N][N];
//l[i][j]=min{dp[i][j],dp[i+1][j]...dp[j][j]};
int read()
{
int x=0,ff=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-') ff=-1;c=getchar();}
while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
return ff*x;
} int main()
{
t=read();
for(int k=1;k<=t;k++)
{
n=read();
memset(f,0,sizeof(f));
memset(dp,0,sizeof(dp));
memset(l,0,sizeof(l));
memset(r,0,sizeof(r));
for(int i=1;i<=n;i++)
{
a[i]=read();
f[i]=f[i-1]+a[i];
}
for(int i=1;i<=n;i++)
{
dp[i][i]=a[i];
l[i][i]=a[i];
r[i][i]=a[i];
}
for(int i=n-1;i>=1;i--)
for(int j=i+1;j<=n;j++)
{
int sum=f[j]-f[i-1];
dp[i][j]=max(sum,max(sum-l[i+1][j],sum-r[i][j-1]));
l[i][j]=min(l[i+1][j],dp[i][j]);
r[i][j]=min(r[i][j-1],dp[i][j]);
}
printf("%d\n",dp[1][n]);
}
return 0;
}

2018.5.1

洛谷 P1430 序列取数 解题报告的更多相关文章

  1. 洛谷 P1430 序列取数

    如果按照http://www.cnblogs.com/hehe54321/p/loj-1031.html的$O(n^3)$做法去做的话是会T掉的,但是实际上那个做法有优化的空间. 所有操作可以分解为由 ...

  2. [洛谷P1430]序列取数

    题目大意:给定一个序列$s$,每个人每轮可以从两端(任选一端)取任意个数的整数,不能不取.在两个人都足够聪明的情况下,求先手的最大得分. 题解:设$f_{i,j}$表示剩下$[i,j]$,先手的最大得 ...

  3. 洛谷 P2022 有趣的数 解题报告

    P2022 有趣的数 题目描述 让我们来考虑1到N的正整数集合.让我们把集合中的元素按照字典序排列,例如当N=11时,其顺序应该为:1,10,11,2,3,4,5,6,7,8,9. 定义K在N个数中的 ...

  4. 洛谷 P2657 [SCOI2009]windy数 解题报告

    P2657 [SCOI2009]windy数 题目描述 \(\tt{windy}\)定义了一种\(\tt{windy}\)数.不含前导零且相邻两个数字之差至少为\(2\)的正整数被称为\(\tt{wi ...

  5. 洛谷_Cx的故事_解题报告_第四题70

    1.并查集求最小生成树 Code: #include <stdio.h> #include <stdlib.h>   struct node {     long x,y,c; ...

  6. 洛谷 P2774 方格取数问题 解题报告

    P2774 方格取数问题 题目背景 none! 题目描述 在一个有 \(m*n\) 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大. ...

  7. 洛谷1303 A*B Problem 解题报告

    洛谷1303 A*B Problem 本题地址:http://www.luogu.org/problem/show?pid=1303 题目描述 求两数的积. 输入输出格式 输入格式: 两个数 输出格式 ...

  8. 洛谷 P3802 小魔女帕琪 解题报告

    P3802 小魔女帕琪 题目背景 从前有一个聪明的小魔女帕琪,兴趣是狩猎吸血鬼. 帕琪能熟练使用七种属性(金.木.水.火.土.日.月)的魔法,除了能使用这么多种属性魔法外,她还能将两种以上属性组合,从 ...

  9. 洛谷 P2606 [ZJOI2010]排列计数 解题报告

    P2606 [ZJOI2010]排列计数 题目描述 称一个\(1,2,...,N\)的排列\(P_1,P_2...,P_n\)是\(Magic\)的,当且仅当对所以的\(2<=i<=N\) ...

随机推荐

  1. EZ 2018 06 02 NOIP2018 模拟赛(十七)

    这次的比赛是真心比较狗,我TM的写了30min的树剖ZZ地直接memset超时了 话说我既然想到差分就应该去写差分的啊! 好了不过这次Rank还挺高的,终于要打进前10了当然是假的了. 好了下面开始讲 ...

  2. JXOI2018简要题解

    JXOI2018简要题解 T1 排序问题 题意 九条可怜是一个热爱思考的女孩子. 九条可怜最近正在研究各种排序的性质,她发现了一种很有趣的排序方法: Gobo sort ! Gobo sort 的算法 ...

  3. python中和生成器协程相关的yield之最详最强解释,一看就懂(一)

    yield是python中一个非常重要的关键词,所有迭代器都是yield实现的,学习python,如果不把这个yield的意思和用法彻底搞清楚,学习python的生成器,协程和异步io的时候,就会彻底 ...

  4. 一次Java内存泄漏调试的有趣经历

    人人都会犯错,但一些错误是如此的荒谬,我想不通怎么会有人犯这种错误.更没想到的是,这种事竟发生在了我们身上.当然,这种东西只有事后才能发现真相.接下来,我将讲述一系列最近在我们一个应用上犯过的这种错误 ...

  5. 在Windows7上如何找到Cookie

    摘要 出于兴趣爱好,前一阵子做了一个网页,网页中需要用到Cookie,但是,根据书上的说明,并没有找打教材中所说的Cookie的位置,本文就主要介绍在计算机(Win7)中Cookie的存放位置,同样适 ...

  6. 类似于PLC上升沿的TRIO代码示例

    需求:    一个自复位按钮,控制灯泡的亮与灭(按钮按一次灯亮,再按一次灯灭依次循环). 简短的代码,若大家有更好的思路可以评论区留言. DIM in_button,op_lamp,var_middl ...

  7. JavaScript之命名空间模式

    前言 命名空间可以被认为是唯一标识符下代码的逻辑分组.为什么会出现命名空间这一概念呢?因为可用的单词数太少,并且不同的人写的程序不可能所有的变量都没有重名现象.在JavaScript中,命名空间可以帮 ...

  8. C_数据结构_数组

    //数组 # include <stdio.h> # include <malloc.h> //包含了 malloc 函数 # include <stdlib.h> ...

  9. linux第一次读书笔记

    第一章 LINUX内核简介 1.1 Unix的历史 1969年的夏天,贝尔实验室的程序员们在一台PDR-7型机上实现了Unix这个全新的操作系统. 1973年,整个Unix系统用C语言进行了重写,给后 ...

  10. Linux列举所有隐藏文件

    ll 命令是 ls -l的缩写 ls -a是列举所有(all)文件,包含隐藏文件,以.开头的文件. ls -l是以列表(list)方式列举文件. http://bbs.chinaunix.net/th ...