G. Game With Triangles: Season 2【Codeforces Round 1009 (Div. 3)】

G. Game With Triangles: Season 2

在这里插入图片描述

思路:

很模板的区间dp
O ( n 3 ) \mathcal{O}(n^3) O(n3),转移方程如下:
dp [ L , R ] = max ⁡ ( max ⁡ L < i < R ( dp [ L + 1 , i − 1 ] + dp [ i + 1 , R − 1 ] + score ( L , i , R ) ) , max ⁡ L ≤ i < R ( dp [ L , i ] + dp [ i + 1 , R ] ) ) \text{dp}_{[L,R]}=\max\left( \max_{L < i < R}\left( \text{dp}_{[L+1,i-1]} + \text{dp}_{[i+1,R-1]} + \text{score}(L,i,R) \right), \max_{L \le i < R}\left( \text{dp}_{[L,i]} + \text{dp}_{[i+1,R]} \right) \right) dp[L,R]=max(L<i<Rmax(dp[L+1,i1]+dp[i+1,R1]+score(L,i,R)),Li<Rmax(dp[L,i]+dp[i+1,R]))

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
#define int long long
#define pb push_back
#define pii pair<int, int>
#define FU(i, a, b) for (int i = (a); i <= (b); ++i)
#define FD(i, a, b) for (int i = (a); i >= (b); --i)
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int n;
int a[405];
int dp[405][405]; // L-R区间上的最大val值
int val(int a, int b, int c) { return a * b * c; }
int modn(int x) { return (x + n - 1) % n + 1; }

void solve() {
    cin >> n;
    FU(i, 1, n) { cin >> a[i]; }
    FU(len, 1, n) {                    // 枚举长度
        for (int l = 1; l <= n; l++) { // 枚举左端点
            int ans = 0;
            int r = modn(l + len - 1); // 枚举右端点
            if (len <= 2) {            // 长度小于等于2 为0
                dp[l][r] = 0;
                continue;
            }
            if (len == 3) {
                dp[l][r] = val(a[l], a[modn(l + 1)], a[r]);
                continue;
            }
            for (int i = modn(l + 1); i != r;
                 i = modn(i + 1)) { // 枚举L+1至R-1上的点i,考虑三角形LiR
                int tmp = val(a[l], a[i], a[r]);
                if (i != modn(l + 1))
                    tmp += dp[modn(l + 1)][modn(i - 1)];
                if (i != modn(r - 1))
                    tmp += dp[modn(i + 1)][modn(r - 1)];
                ans = max(ans, tmp);
            }
            for (int i = l; i != r; i = modn(i + 1)) { // 枚举分为两段区间合
                ans = max(ans, dp[l][i] + dp[modn(i + 1)][r]);
            }
            dp[l][r] = ans;
        }
    }
    int res = 0;
    for (int i = 1; i <= n; i++) {
        res = max(res, dp[i][modn(i + n - 1)]);
    }
    cout << res << endl;
}

signed main() {
    cin.tie(0)->ios::sync_with_stdio(0);
    int T = 1;
    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值