P1063
考虑区间DP
这里可以将 ((2,3)、(3,5)、(5,10)、(10,2)) 看作为一个点,一个点中有两个权值一个是 (head) ,一个是 (tail)
这样考虑区间 dp
(dp[l][r]) 表示 (lsim r) 区间内释放的总能量。
这道题还是一个环形结构,所以可以使用断环成链的方法。
最终的答案是 :(max(dp[i][i + n - 1])) ((1leq ileq n))
那么记忆化就是:
(dp[l][r] = max(dp[l][r],solve(l,k) + solve(k + 1,r) + p[l].F imes p[k].S imes p[r].S))
这样写:
考虑:(2,3)、(3,5)、(5,10)
实际上是 1,2,3
三个点 ,现在 (k) 是 (2) 号点,那么是 (1、2) 号点合并的就是现在的首尾两个权值是 (2、5) 就是 (l.first、k.second)
#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define rep(I, N) for (int I = 1; I <= (N); ++I)
#define repp(I, N) for (int I = 0; I < (N); ++I)
#define FOR(I, A, B) for (int I = (A); I <= (B); ++I)
#define FORR(I, A, B) for (int I = (A); I >= (B); I--)
#define SORT_UNIQUE(c) (sort(c.begin(),c.end()), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define GET_POS(c,x) (lower_bound(c.begin(),c.end(),x)-c.begin())
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define F first
#define S second
using namespace std;
const int N = 200 + 5;
const double eps = 1e-7;
const int mod = 1e9 + 7;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<LL> VL;
typedef vector<PII> VPII;
typedef pair<LL,LL> PLL;
typedef vector<PLL> VPLL;
int a[N];
LL dp[N][N];
PII p[N];
LL dfs(int l,int r)
{
if(dp[l][r] != -1)
return dp[l][r];
if(l == r)
return dp[l][r] = 0;
LL ans = 0;
FOR(i,l,r - 1)
{
ans = max(ans, dfs(l,i) + dfs(i + 1,r) + (LL)p[l].first * p[i].second * p[r].second);
}
return dp[l][r] = ans;
}
int main() {
int n;
cin >> n;
for (int i = 1; i <= n;i++){
cin >> a[i];
a[i + n] = a[i];
}
for (int i = 1; i <= 2 * n - 1;i++)
{
p[i].first = a[i];
p[i].second = a[i + 1];
}
memset(dp, -1, sizeof dp);
p[2 * n].first = a[2 * n];
p[2 * n].F = a[1];
dfs(1,2 * n);
LL ans = 0;
rep(i,n) ans = max(ans,dp[i][i + n - 1]);
cout << ans << endl;
return 0;
}