P1063

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;
}

原文地址:https://www.cnblogs.com/strategist-614/p/12526911.html