【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矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励 ...
随机推荐
- Dos命令以及相关文件的访问
1.转到相关目录 有时候想从当前目录转到D盘,用此目录cd d:是没有用的, 最好用cd /d d:是可以的 2.查看目录文件 dir 3.往服务器上传文件文件 通过文件浏览器上传文件,只适用于Win ...
- python学习笔记02 --------------基础数据类型
python的基本数据类型: 1.基本数据 1.1. 数字类型 1.1.1 整数 int int() #将括号内内容转化为整数类型. 1.1.2 浮点数 float 1.1.3 复 ...
- CSS让内部元素以相反的顺序显示
代码如下: <div id="main" style=" flex-direction: row-reverse;-webkit-flex-direction: r ...
- linux学习总结----shell编程
## 环境变量 ## 全局变量 ``` 常见的全局环境变量 PATH 指令的搜索路径 HOME 用户的家目录 LOGNAME 登录名 SHELL 脚本的类型 使用全局环境变量 echo $PATH 自 ...
- DNA序列 (DNA Consensus String,ACM/ICPC Seoul 2006,UVa1368
题目描述:算法竞赛入门经典习题3-7 题目思路:每列出现最多的距离即最短 #include <stdio.h> #include <string.h> int main(int ...
- [Clr via C#读书笔记]Cp13接口
Cp13接口 类和接口继承 接口只提供签名,不提供实现:等效于契约:凡事能使用具名接口的地方都能够使用实现了的接口. 定义接口 定义很简单,FCL也提供了大量的现成接口供使用: 继承接口 类不能多继承 ...
- Linux内核设计笔记8——下半部
# 下半部笔记 1. 软中断 软中断实现 软中断是在编译期间静态分配,其结构如下所示,结构中包含一个接受该结构体指针作为参数的action函数. struct softirq_action{ void ...
- Memory及其controller芯片整体测试方案(上篇)
如果你最近想买手机,没准儿你一看价格会被吓到手机什么时候偷偷涨价啦! 其实对于手机涨价,手机制造商也是有苦难言,其中一个显著的原因是存储器芯片价格的上涨↗↗↗ >>> 存储器memo ...
- 自测之Lesson5:标准I/O
题目:使用perror函数和strerror函数编写一个程序. 程序代码: #include <stdio.h> #include <errno.h> #include < ...
- Hero In Maze(BFS广搜)
Description 500年前,Jesse是我国最卓越的剑客.他英俊潇洒,而且机智过人^_^.突然有一天,Jesse心爱的公主被魔王困在了一个巨大的迷宫中.Jesse听说这个消息已经是两天以后了, ...