洛谷 P1430 序列取数

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

所有操作可以分解为由两步组成的操作:第一步是在数列的某一端取一个数并加到自己的得分上,第二步是把下一步操作的权利给自己或对方。如果这次操作的前一次是对方的操作,那么在左端或右端取数没有限制;如果这次操作的前一次是自己的操作,那么必须与上一次在相同的一端操作。

令ans[l][r][0/1/2]表示l到r的子序列,上一次操作是(0->对方取)或(1->自己取左端)或(2->自己取右端),先取者的最高得分。则可以得到状态转移方程。复杂度$O(n^2)$。

(枚举状态要按照一定的顺序)

这题卡常!

 1 #pragma GCC diagnostic error "-std=c++11"
 2 #pragma GCC target("avx")
 3 #pragma GCC optimize(3)
 4 #pragma GCC optimize("Ofast")
 5 #pragma GCC optimize("inline")
 6 #pragma GCC optimize("-fgcse")
 7 #pragma GCC optimize("-fgcse-lm")
 8 #pragma GCC optimize("-fipa-sra")
 9 #pragma GCC optimize("-ftree-pre")
10 #pragma GCC optimize("-ftree-vrp")
11 #pragma GCC optimize("-fpeephole2")
12 #pragma GCC optimize("-ffast-math")
13 #pragma GCC optimize("-fsched-spec")
14 #pragma GCC optimize("unroll-loops")
15 #pragma GCC optimize("-falign-jumps")
16 #pragma GCC optimize("-falign-loops")
17 #pragma GCC optimize("-falign-labels")
18 #pragma GCC optimize("-fdevirtualize")
19 #pragma GCC optimize("-fcaller-saves")
20 #pragma GCC optimize("-fcrossjumping")
21 #pragma GCC optimize("-fthread-jumps")
22 #pragma GCC optimize("-funroll-loops")
23 #pragma GCC optimize("-fwhole-program")
24 #pragma GCC optimize("-freorder-blocks")
25 #pragma GCC optimize("-fschedule-insns")
26 #pragma GCC optimize("inline-functions")
27 #pragma GCC optimize("-ftree-tail-merge")
28 #pragma GCC optimize("-fschedule-insns2")
29 #pragma GCC optimize("-fstrict-aliasing")
30 #pragma GCC optimize("-fstrict-overflow")
31 #pragma GCC optimize("-falign-functions")
32 #pragma GCC optimize("-fcse-skip-blocks")
33 #pragma GCC optimize("-fcse-follow-jumps")
34 #pragma GCC optimize("-fsched-interblock")
35 #pragma GCC optimize("-fpartial-inlining")
36 #pragma GCC optimize("no-stack-protector")
37 #pragma GCC optimize("-freorder-functions")
38 #pragma GCC optimize("-findirect-inlining")
39 #pragma GCC optimize("-fhoist-adjacent-loads")
40 #pragma GCC optimize("-frerun-cse-after-loop")
41 #pragma GCC optimize("inline-small-functions")
42 #pragma GCC optimize("-finline-small-functions")
43 #pragma GCC optimize("-ftree-switch-conversion")
44 #pragma GCC optimize("-foptimize-sibling-calls")
45 #pragma GCC optimize("-fexpensive-optimizations")
46 #pragma GCC optimize("-funsafe-loop-optimizations")
47 #pragma GCC optimize("inline-functions-called-once")
48 #pragma GCC optimize("-fdelete-null-pointer-checks")
49 #include<cstdio>
50 #include<cstring>
51 #include<algorithm>
52 using namespace std;
53 int sum[1010],ans[1010][1010][3],a[1010],T,n;
54 inline int read() {
55     int x=0,f=1;char ch=getchar();
56     while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();}
57     while(ch>=‘0‘&&ch<=‘9‘){x*=10;x+=(ch-‘0‘);ch=getchar();}
58     return x*f;
59 }
60 inline void write(int x) {
61     if(x<0) putchar(‘-‘),x=-x;
62     if(x>9) write(x/10);
63     putchar(x%10+‘0‘);
64 }
65 int main()
66 {
67     register int i,l;
68     int r;
69     T=read();
70     while(T--)
71     {
72         memset(ans,0,sizeof(ans));
73         n=read();
74         for(i=1;i<=n;++i)
75             a[i]=read();
76         for(i=1;i<=n;++i)
77             sum[i]=sum[i-1]+a[i];
78         for(i=1;i<=n;++i)
79             ans[i][i][0]=ans[i][i][1]=ans[i][i][2]=a[i];
80         for(i=2;i<=n;++i)
81             for(l=1;l<=n-i+1;++l)
82             {
83                 r=l+i-1;
84                 ans[l][r][0]=max(sum[r]-sum[l-1]-min(ans[l+1][r][0],ans[l][r-1][0]),max(a[l]+ans[l+1][r][1],a[r]+ans[l][r-1][2]));
85                 ans[l][r][1]=max(sum[r]-sum[l-1]-ans[l+1][r][0],a[l]+ans[l+1][r][1]);
86                 ans[l][r][2]=max(sum[r]-sum[l-1]-ans[l][r-1][0],a[r]+ans[l][r-1][2]);
87             }
88         write(ans[1][n][0]);putchar(‘\n‘);
89     }
90     return 0;
91 }

原文地址:https://www.cnblogs.com/hehe54321/p/8431020.html

时间: 2024-12-30 03:27:19

洛谷 P1430 序列取数的相关文章

洛谷 P1005 矩阵取数游戏

题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2.每次取走的各个元素只能是该元素所在行的行首或行尾: 3.每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分 = 被取走的元素值*2^i,其中i表示第i次取数(从1开始编号): 4.游戏结束总得分为m次取数得分之和. 帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分. 输入输

洛谷 P2774 方格取数问题

题目背景 none! 题目描述 在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大.试设计一个满足要求的取数算法.对于给定的方格棋盘,按照取数要求编程找出总和最大的数. 输入输出格式 输入格式: 第 1 行有 2 个正整数 m 和 n,分别表示棋盘的行数和列数.接下来的 m 行,每行有 n 个正整数,表示棋盘方格中的数. 输出格式: 程序运行结束时,将取数的最大总和输出 输入输出样例 输入样例#1: 3 3 1 2

洛谷1004方格取数

P1004 方格取数 题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 0 0 0 0 0 7 0 0 0 0 0 0 14 0 0 0 0 0 21 0 0 0 4 0 0 0 0 15 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . B 某人从图的左上角的A点出发,可以向下行走,也可以向右走,直到到达右下角

洛谷 P1005 矩阵取数游戏 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=1005 题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2.每次取走的各个元素只能是该元素所在行的行首或行尾: 3.每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分 = 被取走的元

dp+高精度(洛谷1005 矩阵取数游戏NOIP 2007 提高第三题)

帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2.每次取走的各个元素只能是该元素所在行的行首或行尾: 3.每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分 = 被取走的元素值*2^i,其中i表示第i次取数(从1开始编号): 4.游戏结束总得分为m次取数得分之和. 帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分. 输入格式: 输入

洛谷P1005 矩阵取数游戏

P1005 矩阵取数游戏 题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2.每次取走的各个元素只能是该元素所在行的行首或行尾: 3.每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分 = 被取走的元素值*2^i,其中i表示第i次取数(从1开始编号): 4.游戏结束总得分为m次取数得分之和. 帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出

[洛谷P2774] 方格取数问题

题意 在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大. 想法 我们将问题转化为:一开始所有格子都选,之后去掉价值和最少的一些格子使剩下的格子合法. 将方格黑白染色,白格子连向S,黑格子连向T,边权为这个格子的值(也就是说将格子转移到边上). 相邻的黑白格子间连INF的边.(这样每条从S到T的路径都为 S->白格子->黑格子->T , 这两个格子不能同时选,S->白格子 与 黑格子->T 间必

【动态规划】洛谷P1004方格取数

题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 0 0 0 0 0 7 0 0 0 0 0 0 14 0 0 0 0 0 21 0 0 0 4 0 0 0 0 15 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . B 某人从图的左上角的A点出发,可以向下行走,也可以向右走,直到到达右下角的B 点.在走过的路上

洛谷[P1004]方格取数

题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 0 0 0 0 0 7 0 0 0 0 0 0 14 0 0 0 0 0 21 0 0 0 4 0 0 0 0 15 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . B 某人从图的左上角的A点出发,可以向下行走,也可以向右走,直到到达右下角的B 点.在走过的路上