这个题有两种解法。
第一种贪心:总是只选择最低点和最高点。这样对答案的贡献肯定是最大的。
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=150000+5;
int p;
int t[maxn];
int main() {
while(cin>>p) {
for(int i=1; i<=p; ++i) {
cin>>t[i];
}
int ans=t[1];
int tmp;
bool flag=true;
for(int i=2; i<=p; ++i) {
if(flag) {//递减
if(t[i]>t[i-1]) {
tmp=t[i-1];
flag=false;
i--;
}
}
else{//上升
if(t[i]<t[i-1]){
ans+=t[i-1]-tmp;
flag=true;
i--;
}
}
}
if(!flag){
ans+=t[p]-tmp;
}
cout<<ans<<endl;
}
return 0;
}
第二种动态规划:两个dp函数,dp1[i] 前一步为奇数到i的最大值 ,dp2[i] 前一步为偶数到i的最大值。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=150005;
int dp1[maxn],dp2[maxn],p,tmp;
//dp1[i] 前一步为奇数到i的最大值
//dp2[i] 前一步为偶数到i的最大值
int main(){
cin>>p;
dp1[0]=dp2[0]=0;
for(int i=1;i<=p;++i){
cin>>tmp;
dp1[i]=max(dp1[i-1],dp2[i-1]-tmp);
dp2[i]=max(dp2[i-1],dp1[i-1]+tmp);
}
cout<<max(dp1[p],dp2[p])<<endl;
return 0;
}

本文探讨了通过传送门问题的两种解决方案。一种是贪心算法,通过选择序列中的最低点和最高点来最大化答案的贡献;另一种是动态规划方法,使用两个dp函数分别计算前一步为奇数和偶数时的最大值。
1187





