You are given two integer arrays nums and multipliers of size n and m respectively, where n >= m. The arrays are 1-indexed.
You begin with a score of 0. You want to perform exactly m operations. On the ith operation (1-indexed), you will:
Choose one integer x from either the start or the end of the array nums.
Add multipliers[i] * x to your score.
Remove x from the array nums.
Return the maximum score after performing m operations.
Example 1:
Input: nums = [1,2,3], multipliers = [3,2,1]
Output: 14
Explanation: An optimal solution is as follows:
The total score is 9 + 4 + 1 = 14.
Example 2:
Input: nums = [-5,-3,-3,-2,7,1], multipliers = [-10,-5,3,4,6]
Output: 102
Explanation: An optimal solution is as follows:
The total score is 50 + 15 - 9 + 4 + 42 = 102.
Constraints:
基本就是 dp 的思路, start, end 分别是 nums 从左到右和从右到左的 index, i 是 multipliers 从左到右的 index, dp[start][end][i]=max(nums[start] _ multipliers[i] + dp[start+1][end][i+1], nums[end] _ multipliers[i] + dp[start][end-1][i+1]). 这里的 end 其实可以通过 start 和 i 计算出来, end = nums.len() - 1 - (i - s)
use std::collections::HashMap;
impl Solution {
fn dp(
nums: &Vec<i32>,
multipliers: &Vec<i32>,
s: usize,
i: usize,
cache: &mut HashMap<(usize, usize), i32>,
) -> i32 {
let e = nums.len() - 1 - (i - s);
if i == multipliers.len() - 1 {
if multipliers[i] > 0 {
let ans = nums[s].max(nums[e]) * multipliers[i];
cache.insert((s, i), ans);
return ans;
}
let ans = nums[s].min(nums[e]) * multipliers[i];
cache.insert((s, i), ans);
return ans;
}
if let Some(c) = cache.get(&(s, i)) {
return *c;
}
let start = nums[s] * multipliers[i]
+ if let Some(c) = cache.get(&(s + 1, i + 1)) {
*c
} else {
Solution::dp(nums, multipliers, s + 1, i + 1, cache)
};
let end = nums[e] * multipliers[i]
+ if let Some(c) = cache.get(&(s, i + 1)) {
*c
} else {
Solution::dp(nums, multipliers, s, i + 1, cache)
};
let ans = start.max(end);
cache.insert((s, i), ans);
ans
}
pub fn maximum_score(nums: Vec<i32>, multipliers: Vec<i32>) -> i32 {
Solution::dp(&nums, &multipliers, 0, 0, &mut HashMap::new())
}
}