解题思路:动态规划
这是一道区间dp的题目。首先第一步是把区间从n扩展到2n,这样就不用尾首循环了。
接下来按照区间大小,从小到大循环,先计算小区间的最优解,再计算大区间的最优解。
状态转移方程:dp[l][r] = max(dp[l][j] + dp[j][r] + a[l] * a[j] * a[r]), j ∈ [ l + 1, r - 1 ]
注意本题的数据范围:由于珠子的值满足val <= 1000,因此每次获取的能量不超过10^9;n <= 100表示最多100个珠子,故而能量总和不超过10^11。因此使用long long,并且计算的中途不要对109+7取模(如果你在计算中途对109+7取模,则取模后的值就不是最大值了,可能导致后续的dp错误)。
下面贴出cpp代码。
#include <iostream>
#include <vector>
using namespace std;
int main() {
const int mod = 1e9 + 7;
int n;
cin >> n;
vector<int> a(n + n);
vector<vector<long long>> dp(n + n, vector<long long>(n + n, 0));
for (int i = 0; i < n; ++i) {
cin >> a[i];
a[i + n] = a[i];
}
for (int i = 2; i < n; ++i) {
for (int l = 0; l < n; ++l) {
int r = l + i;
for (int j = l + 1; j < r; ++j) {
dp[l][r] = max(dp[l][r], dp[l][j] + dp[j][r] + a[l] * a[j] * a[r]);
}
if(r < n) dp[l + n][r + n] = dp[l][r];
}
}
long long ans = 0;
for (int l = 0; l < n; ++l) {
int r = l + n;
for (int j = l + 1; j < r; ++j) {
ans = max(ans, dp[l][j] + dp[j][r] + a[l] * a[j] * a[r]);
}
}
cout << (ans % mod);
}



京公网安备 11010502036488号