洛谷 P1430 序列取数 解题报告
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 序列取数 解题报告的更多相关文章
- 洛谷 P1430 序列取数
如果按照http://www.cnblogs.com/hehe54321/p/loj-1031.html的$O(n^3)$做法去做的话是会T掉的,但是实际上那个做法有优化的空间. 所有操作可以分解为由 ...
- [洛谷P1430]序列取数
题目大意:给定一个序列$s$,每个人每轮可以从两端(任选一端)取任意个数的整数,不能不取.在两个人都足够聪明的情况下,求先手的最大得分. 题解:设$f_{i,j}$表示剩下$[i,j]$,先手的最大得 ...
- 洛谷 P2022 有趣的数 解题报告
P2022 有趣的数 题目描述 让我们来考虑1到N的正整数集合.让我们把集合中的元素按照字典序排列,例如当N=11时,其顺序应该为:1,10,11,2,3,4,5,6,7,8,9. 定义K在N个数中的 ...
- 洛谷 P2657 [SCOI2009]windy数 解题报告
P2657 [SCOI2009]windy数 题目描述 \(\tt{windy}\)定义了一种\(\tt{windy}\)数.不含前导零且相邻两个数字之差至少为\(2\)的正整数被称为\(\tt{wi ...
- 洛谷_Cx的故事_解题报告_第四题70
1.并查集求最小生成树 Code: #include <stdio.h> #include <stdlib.h> struct node { long x,y,c; ...
- 洛谷 P2774 方格取数问题 解题报告
P2774 方格取数问题 题目背景 none! 题目描述 在一个有 \(m*n\) 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大. ...
- 洛谷1303 A*B Problem 解题报告
洛谷1303 A*B Problem 本题地址:http://www.luogu.org/problem/show?pid=1303 题目描述 求两数的积. 输入输出格式 输入格式: 两个数 输出格式 ...
- 洛谷 P3802 小魔女帕琪 解题报告
P3802 小魔女帕琪 题目背景 从前有一个聪明的小魔女帕琪,兴趣是狩猎吸血鬼. 帕琪能熟练使用七种属性(金.木.水.火.土.日.月)的魔法,除了能使用这么多种属性魔法外,她还能将两种以上属性组合,从 ...
- 洛谷 P2606 [ZJOI2010]排列计数 解题报告
P2606 [ZJOI2010]排列计数 题目描述 称一个\(1,2,...,N\)的排列\(P_1,P_2...,P_n\)是\(Magic\)的,当且仅当对所以的\(2<=i<=N\) ...
随机推荐
- 浅淡volatile原理
Volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的“可见性” Volatile的官方定义 Java语言规范第三版中对volatile的定义如下: java编程语言允 ...
- for循环两个略骚的写法
骚写法 或许你知道,总之我觉得很酷,希望你也这么认为. 递增遍历 最常见场景,从 0 到 10 的遍历,不输出 10: for(let i = -1; ++i < 10;) { console. ...
- 利用卷积神经网络(VGG19)实现火灾分类(附tensorflow代码及训练集)
源码地址 https://github.com/stephen-v/tensorflow_vgg_classify 1. VGG介绍 1.1. VGG模型结构 1.2. VGG19架构 2. 用Ten ...
- ruby安装及升级
在centos6.x下执行上面的"gem install redis"操作可能会报错,坑很多!默认yum安装的ruby版本是1.8.7,版本太低,需要升级到ruby2.2以上,否则 ...
- MyEclipse项目里面出现红叉的解决方案?
一般出现在从别处import的项目上,只有项目文件夹上有红叉,其他地方都正常,现总结个人的几个解决方案: 有几种可能: 1,编码设置是否一致,也即是你项目原来的编码和现在eclipse用的默认编码 ...
- Flask-论坛开发-2-Jinja2模板
对Flask感兴趣的,可以看下这个视频教程:http://study.163.com/course/courseLearn.htm?courseId=1004091002 1. Jinja2 模板介绍 ...
- HTML 引入Css样式
- RequestHolder工具类
package com.inspire.ssm.common; import com.inspire.ssm.model.SysUser; import javax.servlet.http.Http ...
- Activiti reassign task to another user
//早先胡乱尝试的其他方法,可能对于以后深入学习Activiti有些用处. //taskService.delegateTask(taskId, receiveUserId); //taskServi ...
- Redis应用一例(存证数量用计数器实现)
public Long getCreationCounter() { String host =PropertyUtils.getPropertyValue("redis.server.ho ...