题目
B. Marvolo Gaunt's Ring
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Professor Dumbledore is helping Harry destroy the Horcruxes. He went to Gaunt Shack as he suspected a Horcrux to be present there. He saw Marvolo Gaunt's Ring and identified it as a Horcrux. Although he destroyed it, he is still affected by its curse. Professor Snape is helping Dumbledore remove the curse. For this, he wants to give Dumbledore exactly x drops of the potion he made.
Value of x is calculated as maximum of p·a**i + q·a**j + r·a**k for given p, q, r and array a1, a2, ... a**n such that 1 ≤ i ≤ j ≤ k ≤ n. Help Snape find the value of x. Do note that the value of x may be negative.
Input
First line of input contains 4 integers n, p, q, r ( - 109 ≤ p, q, r ≤ 109, 1 ≤ n ≤ 105).
Next line of input contains n space separated integers a1, a2, ... a**n ( - 109 ≤ a**i ≤ 109).
Output
Output a single integer the maximum value of p·a**i + q·a**j + r·a**k that can be obtained provided 1 ≤ i ≤ j ≤ k ≤ n.
Examples
input
Copy
5 1 2 3 1 2 3 4 5
output
Copy
30
input
Copy
5 1 2 -3 -1 -2 -3 -4 -5
output
Copy
12
Note
In the first sample case, we can take i = j = k = 5, thus making the answer as 1·5 + 2·5 + 3·5 = 30.
In second sample case, selecting i = j = 1 and k = 5 gives the answer 12.
思路 背包dp
因为\(p, q, r\)是有顺序的,所以状态转移是确定的,\(dp[i][j]\)表示考虑前i个数,第j个数选择\(p, q, r\)中的数进行乘积,每个数我们都可以选或不选,所以状态转移可以写成:
\(\begin{equation} dp[i][j]=\left\{ \begin{aligned} dp[i][0] = max(dp[i - 1][0], a[i] * p)\\ dp[i][1] = max(dp[i - 1][1], a[i] * q)\\dp[i][2] = max(dp[i - 1][2], a[i] * r)\\ \end{aligned} \right . \end{equation}\)
Code
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
const long long INF = 9e18 + 10;
long long dp[N][3];
int main() {
ios::sync_with_stdio(0);
long long n, p, q, r, a[N]; cin >> n >> p >> q >> r;
for(int i = 1; i <= n; i ++) cin >> a[i];
dp[0][0] = dp[0][1] = dp[0][2] = -INF;
for(int i = 1; i <= n; i ++) {
dp[i][0] = max(dp[i - 1][0], p * a[i]);
dp[i][1] = max(dp[i - 1][1], dp[i][0] + q * a[i]);
dp[i][2] = max(dp[i - 1][2], dp[i][1] + r * a[i]);
}
cout << dp[n][2];
}