1007 Maximum Subsequence Sum(两种思路)

Posted CSU迦叶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1007 Maximum Subsequence Sum(两种思路)相关的知识,希望对你有一定的参考价值。

1.解法1 思路

对于动态规划来说,最关键的就是找到状态转移方程,本题设置一个前向数组,元素predp[i]表示的是以元素i结尾的连续数列和的最大值,转移方程是predp[i] = max(predp[i-1]+a[i],a[i])。要做的事就是完成这个dp数组,然后找到最大的dp[i]。

根据i可以直接得到结束元素,那开始元素怎么办呢?我们还需要另开一个计数数组n[maxn],记录下数目。

注意:要获得坐标尽可能小的起始元素和终止元素,体现在代码的两个地方

1是:哪怕前面的元素加上是鸡肋,为了起始坐标小,也把它加上

for(int i=1;i<n;i++){
	if(predp[i-1]+a[i]>=a[i]){
		num[i] = num[i-1]+1;
		predp[i] = predp[i-1]+a[i];
	}else{
		num[i] = 1;
		predp[i] = a[i];	
	}
}

 2是:在挑选最大dp[i]的时候,哪怕后面出现了同样大的,也不要

int preI,preMax = -1;
for(int i=0;i<n;i++){
	if(predp[i]>preMax){
		preMax = predp[i];
		preI = i;
	}
}

2.解法2 思路

设置一前一后两个状态转移方程,并且由于最后希望起始坐标和终止坐标都尽可能小,所以对于前向数组找最大下标的时候,必须是大于,才能允许坐标被增大,对于反向数组找最大下标的时候,满足大于等于,就允许坐标被减小。原理是:正向得到最大值的数列,和反向得到最大值的数列是同一个。

3.解法1 AC代码

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<bits/stdc++.h>
using namespace std;

const int INF = 1000000000;//10的9次方 
const int maxn = 100010;
const double eps = 1e-3;

int n;
int a[maxn];
int predp[maxn];
int num[maxn];
bool isSpe = true;

int main(){
	
	
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
		if(a[i]>=0)isSpe = false;//说明不是特例 
	}
	
	if(isSpe){
		printf("0 %d %d\\n",a[0],a[n-1]);
		return 0;
	}
	
	//解决predp[0]和num[0]
	predp[0] = a[0];
	num[0] = 1;
	
	for(int i=1;i<n;i++){
		if(predp[i-1]+a[i]>=a[i]){
			num[i] = num[i-1]+1;
			predp[i] = predp[i-1]+a[i];
		}else{
			num[i] = 1;
			predp[i] = a[i];	
		}
	}
	
	int preI,preMax = -1;
	for(int i=0;i<n;i++){
		if(predp[i]>preMax){
			preMax = predp[i];
			preI = i;
		}
	}
	
	
	
	printf("%d %d %d\\n",preMax,a[preI-num[preI]+1],a[preI]);	
	
	
	return 0; 
}

4.解法2 非满分(22/25)代码

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<bits/stdc++.h>
using namespace std;

const int INF = 1000000000;//10的9次方 
const int maxn = 100010;
const double eps = 1e-3;

int n;
int a[maxn];
int predp[maxn];
int postdp[maxn];
bool isSpe = true;

int main(){
	
	
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
		if(a[i]>=0)isSpe = false;//说明不是特例 
	}
	
	if(isSpe){
		printf("0 %d %d\\n",a[0],a[n-1]);
		return 0;
	}
	
	predp[0] = max(0,a[0]);
	for(int i=1;i<n;i++){
		predp[i] = max(predp[i-1]+a[i],a[i]);
	}
	int preI,preMax = -1;
	for(int i=0;i<n;i++){
		if(predp[i]>preMax){
			preMax = predp[i];
			preI = i;
		}
	}
	
	postdp[n-1] = max(0,a[n-1]);
	for(int i=n-2;i>=0;i--){
		postdp[i] = max(postdp[i+1]+a[i],a[i]);
	}
	int postI,postMax = -1;
	for(int i=n-1;i>=0;i--){
		if(postdp[i]>=postMax){
			postMax = postdp[i];
			postI = i;
		}
	}
	
	printf("%d %d %d\\n",postMax,a[postI],a[preI]);	
	
	
	return 0; 
}

以上是关于1007 Maximum Subsequence Sum(两种思路)的主要内容,如果未能解决你的问题,请参考以下文章

1007 Maximum Subsequence Sum(25 分)

1007 Maximum Subsequence Sum

1007. Maximum Subsequence Sum (25)

1007. Maximum Subsequence Sum (25)

1007. Maximum Subsequence Sum (25) 动态规划

1007 Maximum Subsequence Sum (25)(25 分)