【DP优化】【P1430】序列取数
Description
给定一个长为n的整数序列,由A和B轮流取数(A先取)。每个人可从序列的左端或右端取若干个数(至少一个),但不能两端都取。所有数都被取走后,两人分别统计所取数的和作为各自的得分。假设A和B都足够聪明,都使自己得分尽量高,求A的最终得分。
Input
第一行,一个正整数T,表示有T组数据。
接着T行,每行第一个数为n,接着n个整数表示给定的序列.
Output
输出T行,每行一个整数,表示A的得分
Sample Input
2
1 -1
2 1 2
Sample Output
-1
3
Hint
时限3s。
对于100%的数据,\(n \leq 1000, T \leq 100\)
Solution
显然是博弈DP。考虑设\(f_{i,j}\)是区间\([i,j]\)先手取数的最大答案。转移显然为
\(f_{i,j}=sum_j-sum_i-min{f_{k,j},f_{i,k}}\),其中满足\(i~<~k~<~j\)。枚举\(k\)进行转移,复杂度是\(O(n^3)\)。直接凉凉。
状态已经是\(O(n^2)\)无法优化。考虑对转移进行优化。考虑枚举\(k\)是求一定区间内\(f\)的最大值。这个\(f\)的区间是从小到大枚举的,所以可以维护区间内\(f\)的最大值。具体的,设\(l_{i,j}\)代表\(max{f_{i,k}}\),\(r_{i,j}\)代表\(max{f_{k,r}}\),其中满足\(i~<~k~<~j\)。
这样转移方程就变成\(f_{i,j}=sum_j-sum_i-min{l_{i,j},r_{i,j}}\)。这样使用DP对DP进行优化,转移变成\(O(1)\)的,可以通过本题。
其中\(l_{i,j}=max{l_{i,j-1},f_{i,j}}\),\(r\)的转移同理。
Code
#include<cstdio>
#include<cstring>
#define rg register
#define ci const int
#define cl const long long int
typedef long long int ll;
namespace IO {
char buf[50];
}
template<typename T>
inline void qr(T &x) {
char ch=getchar(),lst=' ';
while(ch>'9'||ch<'0') lst=ch,ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
if (lst=='-') x=-x;
}
template<typename T>
inline void write(T x,const char aft,const bool pt) {
if(x<0) {putchar('-');x=-x;}
int top=0;
do {
IO::buf[++top]=x%10+'0';
x/=10;
} while(x);
while(top) putchar(IO::buf[top--]);
if(pt) putchar(aft);
}
template <typename T>
inline T mmax(const T a,const T b) {if(a>b) return a;return b;}
template <typename T>
inline T mmin(const T a,const T b) {if(a<b) return a;return b;}
template <typename T>
inline T mabs(const T a) {if(a<0) return -a;return a;}
template <typename T>
inline void mswap(T &a,T &b) {T temp=a;a=b;b=temp;}
const int maxn = 1010;
int t,n;
int MU[maxn],frog[maxn][maxn],lmax[maxn][maxn],rmax[maxn][maxn],sum[maxn];
void clear();
int main() {
qr(t);
while(t--) {
clear() ;
qr(n);
for(rg int i=1;i<=n;++i) qr(MU[i]);
for(rg int i=1;i<=n;++i) lmax[i][i]=rmax[i][i]=frog[i][i]=MU[i],sum[i]=sum[i-1]+MU[i];
for(rg int i=1;i<n;++i) {
for(rg int j=1;j<n;++j) {
rg int r=i+j;if(r>n) break;
frog[j][r]=sum[r]-sum[j-1]-mmin(0,mmin(lmax[j][r-1],rmax[j+1][r]));
lmax[j][r]=mmin(frog[j][r],lmax[j][r-1]);rmax[j][r]=mmin(frog[j][r],rmax[j+1][r]);
}
}
write(frog[1][n],'\n',true);
}
return 0;
}
void clear() {
memset(MU,0,sizeof MU);
memset(sum,0,sizeof sum);
memset(frog,0,sizeof frog);
memset(lmax,0,sizeof lmax);
memset(rmax,0,sizeof rmax);
n=0;
}
Summary
在DP因为复杂度较高而无法承受时,考虑对转移进行优化。常见的如维护区间最大/最小值,通过数据结构或者DP进行优化。
【DP优化】【P1430】序列取数的更多相关文章
- 洛谷 P1430 序列取数 解题报告
P1430 序列取数 题目描述 给定一个长为\(n\)的整数序列\((n<=1000)\),由\(A\)和\(B\)轮流取数(\(A\)先取).每个人可从序列的左端或右端取若干个数(至少一个), ...
- 洛谷 P1430 序列取数
如果按照http://www.cnblogs.com/hehe54321/p/loj-1031.html的$O(n^3)$做法去做的话是会T掉的,但是实际上那个做法有优化的空间. 所有操作可以分解为由 ...
- 【Luogu】P1430序列取数(DP)
题目链接 博弈DP太喵了qwq 设f[i][j]表示剩下区间[i,j]要取,先手最大值 明显我们要从这区间里面拿个最大的 就等价于这段区间的前缀和,我们要给对手留下个最小的 就是f[i][j]=sum ...
- [洛谷P1430]序列取数
题目大意:给定一个序列$s$,每个人每轮可以从两端(任选一端)取任意个数的整数,不能不取.在两个人都足够聪明的情况下,求先手的最大得分. 题解:设$f_{i,j}$表示剩下$[i,j]$,先手的最大得 ...
- 「LuoguP1430」 序列取数(区间dp
题目描述 给定一个长为n的整数序列(n<=1000),由A和B轮流取数(A先取).每个人可从序列的左端或右端取若干个数(至少一个),但不能两端都取.所有数都被取走后,两人分别统计所取数的和作为各 ...
- HDU 1565&1569 方格取数系列(状压DP或者最大流)
方格取数(2) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU3045 Picnic Cows (斜率DP优化)(数形结合)
转自PomeCat: "DP的斜率优化--对不必要的状态量进行抛弃,对不优的状态量进行搁置,使得在常数时间内找到最优解成为可能.斜率优化依靠的是数形结合的思想,通过将每个阶段和状态的答案反映 ...
- 洛谷 P1004 方格取数 【多进程dp】
题目链接:https://www.luogu.org/problemnew/show/P1004 题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 ...
- 51Nod 1084:矩阵取数问题 V2(多维DP)
1084 矩阵取数问题 V2 基准时间限制:2 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注 一个M*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励 ...
随机推荐
- Selenium自动化测试基础
如有任何学习问题,可以添加作者微信:lockingfree 目录 Selenium自动化测试基础 Selenium自动化测试第一天(上) Selenium自动化测试第一天(下) Selenium自动化 ...
- docker官网安装
最近发现一些同学居然不会安装docker,难,不难,只是“网络不好”! 如果是学习的话,目前我发现的比较好的方法还是到清华的开源镜像网站: https://mirror.tuna.tsinghua.e ...
- 聊聊Bug引发事故该不该追求责任
最近读极客时间朱赟的一篇文章有感,在这也聊一下,在互联网的公司大多数以迭代的方式上线需求,节奏一般都比较快,经常会一个需求当天来了第二天就上线,开发和测试时间总共就两天,中间还穿插着别的需求测试,不像 ...
- 孤荷凌寒自学python第七十八天开始写Python的第一个爬虫8
孤荷凌寒自学python第七十八天开始写Python的第一个爬虫8 (完整学习过程屏幕记录视频地址在文末) 今天在上一天的基础上继续完成对我的第一个代码程序的书写. 到今天止基本完成了对docx模块针 ...
- python内建模块Collections
# -*- coding:utf-8 -*- # OrderedDict可以实现一个FIFO(先进先出)的dict, # 当容量超出限制时,先删除最早添加的Key: from collections ...
- ubuntu samba配置注意事项
1. 下载samba前, ubuntu镜像源需要更新为国内源,否则samba的安装会非常慢 亲测,清华的镜像源速度满足要求. A.登录 https://mirrors.tuna.tsinghua.ed ...
- Asp.net之数组应用
string[] abc=new string[8]{"1","2","3","4","1",&qu ...
- Microservices with Spring Boot
找到一套比较不错的Spring Boot/Cloud入门教程,推荐一下. https://dzone.com/users/1041459/ranga_pec.html
- POJ 1739 Tony's Tour(插头DP)
Description A square township has been divided up into n*m(n rows and m columns) square plots (1< ...
- 美美哒rand()函数
2016.3.7 天气:大雪都已经三月份竟然还下了这么大的雪,真是少见呀.今天为了提交软件工程的作业我们需要注册git的账号,真是前途艰难呀,后台服务器都要爆炸了,其实我觉得这个平台的服务器 ...