思路:①枚举a[j],a[i]和a[k]分别用前缀最小值最大值和后缀最小值和后缀最大值确定。
②dp,dp[i][j]表示到第j为止,前i+1个值加起来的最大值。
代码:
代码①:
#include<bits/stdc++.h> using namespace std; #define ll long long const int N=1e5+5; const int INF=0x3f3f3f3f; int a[N]; int premx[N]; int premn[N]; int sufmx[N]; int sufmn[N]; int main() { ios::sync_with_stdio(false); cin.tie(0); ll n,p,q,r; cin>>n>>p>>q>>r; for(int i=1;i<=n;i++)cin>>a[i]; premx[0]=-INF,premn[0]=INF; for(int i=1;i<=n;i++)premx[i]=max(premx[i-1],a[i]),premn[i]=min(premn[i-1],a[i]); sufmx[n+1]=-INF,sufmn[n+1]=INF; for(int i=n;i>=1;i--)sufmx[i]=max(sufmx[i+1],a[i]),sufmn[i]=min(sufmn[i+1],a[i]); ll ans=-8000000000000000000; for(int i=1;i<=n;i++)ans=max(ans,max(p*premx[i],p*premn[i])+q*a[i]+max(r*sufmx[i],r*sufmn[i])); cout<<ans<<endl; return 0; }
代码②:
#include<bits/stdc++.h> using namespace std; #define ll long long #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) const int N=1e5+5; const ll _INF=-8e18; ll dp[3][N]; int a[N]; int main() { ios::sync_with_stdio(false); cin.tie(0); ll p,q,r,n; cin>>n>>p>>q>>r; for(int i=1;i<=n;i++)cin>>a[i]; dp[0][0]=_INF; dp[1][0]=_INF; dp[2][0]=_INF; for(int i=1;i<=n;i++) { dp[0][i]=max(dp[0][i-1],p*a[i]); dp[1][i]=max(dp[1][i-1],dp[0][i]+q*a[i]); dp[2][i]=max(dp[2][i-1],dp[1][i]+r*a[i]); } cout<<dp[2][n]<<endl; return 0; }