
一只贪吃的猴子,来到一个果园,发现许多串香蕉排成一行,每串香蕉上有若干根香蕉。每串香蕉的根数由数组numbers给出。猴子获取香蕉每次都只能从行的开头或者末尾获取,并且只能获取N次,求猴子最多能获取多少根香蕉。
第一行为数组numbers的长度
第二行为数组numbers的值,每个数字通过空格分开
第三行输入为N,表示获取的次数
1 <= numbers.length <= 100000
1<= numbers[i] <= 100
1 <= N <= numbers.length
按照题目要求能获取的最大数值
7
1 2 2 7 3 6 1
3
10
要解决这个问题,可以使用动态规划的方法。具体来说,我们需要找到一个长度为 N 的子序列,使得这个子序列的和最大。这个子序列可以从数组的开头或末尾获取。
dp,其中 dp[i][j] 表示从数组的第 i 个元素到第 j 个元素中,猴子获取 k 次香蕉的最大值。k,我们可以选择从数组的开头或末尾获取香蕉,更新 dp 数组。dp[0][n-1] 中的最大值。#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int max_bananas(vector<int>& numbers, int N) {
int n = numbers.size();
if (N >= n) {
return accumulate(numbers.begin(), numbers.end(), 0);
}
// 初始化 dp 数组
vector<vector<int>> dp(N + 1, vector<int>(n, 0));
// 计算前缀和
vector<int> prefix_sum(n + 1, 0);
for (int i = 1; i <= n; ++i) {
prefix_sum[i] = prefix_sum[i - 1] + numbers[i - 1];
}
// 动态规划
for (int k = 1; k <= N; ++k) {
for (int i = 0; i + k <= n; ++i) {
int j = i + k - 1;
dp[k][i] = max(dp[k - 1][i + 1] + numbers[i], dp[k - 1][i] + numbers[j]);
}
}
// 返回结果
return dp[N][0];
}
int main() {
int n;
cin >> n;
vector<int> numbers(n);
for (int i = 0; i < n; ++i) {
cin >> numbers[i];
}
int N;
cin >> N;
cout << max_bananas(numbers, N) << endl;
return 0;
}N 是否大于等于数组的长度 n,如果是,则直接返回数组的总和。prefix_sum,用于快速计算任意子数组的和。dp[k][i] 表示从数组的第 i 个元素到第 i + k - 1 个元素中,猴子获取 k 次香蕉的最大值。k,我们遍历所有可能的起始位置 i,并更新 dp[k][i]。dp[N][0]。原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。