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 (25)
1007. Maximum Subsequence Sum (25)