简单DP【p2642】双子序列最大和
2018-10-24 15:37
495 查看
Description
给定一个长度为n的整数序列,要求从中选出两个连续子序列,使得这两个连续子序列的序列和之和最大,最终只需输出最大和。一个连续子序列的和为该子序列中所有数之和。每个连续子序列的最小长度为1,并且两个连续子序列之间至少间隔一个数。
Input
第一行是一个整数表示n。
第二行是n个整数表示整数序列。
Output
一个数,两个连续子序列的序列和之和。
动态规划.这不某年初赛题
我们设\(l[i]\)代表从\(1\)到\(i\)的最大的子序列的和,\(r[i]\)代表从\(i\)到\(n\)的最大的子序列的和.(可以不包含\(i\))
然后维护的话,每次转移取\(max\)
\[
l[i]=max(l[i-1]+x[i],x[i])\\
r[i]=max(r[i+1]+x[i],x[i])
\]
然后取前缀\(max\)和后缀\(max\).
取\(ans\)的时候就是
\[
ans=max(ans,l[i-1]+r[i+1])
\]
(因为题目要求至少间隔一个数~w~
还有,由于可能出负数,所以\(l\)数组要从\(2\)开始.\(r\)数组要从\(n-1\)开始
代码
#include<cstdio> #include<cctype> #include<iostream> #define R register using namespace std; inline void in(int &x) { int f=1;x=0;char s=getchar(); while(!isdigit(s)){if(s=='-')f=-1;s=getchar();} while(isdigit(s)){x=x*10+s-'0';s=getchar();} x*=f; } int n,ans=-2147483644; int l[1000008],r[1000008],x[1000008]; int main() { in(n); for(R int i=1;i<=n;i++)in(x[i]); l[1]=x[1]; for(R int i=2;i<=n;i++) l[i]=max(l[i-1]+x[i],x[i]); for(R int i=2;i<=n;i++) l[i]=max(l[i-1],l[i]); r =x ; for(R int i=n-1;i>=1;i--) r[i]=max(r[i+1]+x[i],x[i]); for(R int i=n-1;i>=1;i--) r[i]=max(r[i+1],r[i]); for(R int i=2;i<n;i++) ans=max(ans,r[i+1]+l[i-1]); printf("%d",ans); }
相关文章推荐
- 简单dp 最大连续子序列
- (hdu step 3.2.1)Max Sum(简单dp:求最大子序列和、起点、终点)
- hdoj最大连续子序列 (简单dp)
- 题目1011:最大连续子序列 简单dp
- 和最大的子序列(简单dp)
- ZOJ1733 | | HDU1159简单的DP求两个字符串最大子序列的长度,没啥好说的,照着书上敲得。
- 最大连续子序列 简单dp
- POJ 2479 + POJ 2593(DP 最大双子序列 ^_^)
- 51Nod 1062 序列中最大的数 | 简单DP
- P2642 双子序列最大和
- HDU 1231 最大连续子序列 简单dp
- HDU1231 最大连续子序列 DP
- POJ 2479 (算不上简单的dp,可以称为简单的求两个子串和最大)
- 【51Nod1202】子序列个数(简单dp)
- 最大子序列和——简单问题的不简单之处
- [洛谷P2642]双子序列最大和
- 最大连续子序列和(经典DP) 之 hdu 1231 最大连续子序列
- hdu 1559 最大子矩阵 (简单dp)
- hdu1003 Max Sum(最大子序列和) —— dp
- hdu 1087 Super Jumping! Jumping! Jumping!(dp:上升子序列最大和)