1 条题解

  • 0
    @ 2026-2-17 10:09:52
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int MAXN = 805;  // 2*400=800,预留空间
    const int INF = 0x3f3f3f3f;  // 足够大的数,用于最小值初始化
    
    int a[MAXN], s[MAXN];  // a存储石子数组,s是前缀和数组
    int dp_min[MAXN][MAXN], dp_max[MAXN][MAXN];
    
    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; ++i) {
            s[i] = s[i - 1] + a[i];
        }
        // 初始化DP数组
        memset(dp_min, 0x3f, sizeof(dp_min));
        memset(dp_max, 0, sizeof(dp_max));
        for (int i = 1; i <= 2 * n; ++i) {
            dp_min[i][i] = 0;
            dp_max[i][i] = 0;
        }
        // 枚举区间长度,从2开始(长度1已初始化)
        for (int len = 2; len <= n; ++len) {
            // 枚举左端点,保证右端点不越界
            for (int l = 1; l + len - 1 <= 2 * n; ++l) {
                int r = l + len - 1;
                // 枚举分割点,更新DP值
                for (int k = l; k < r; ++k) {
                    dp_min[l][r] = min(dp_min[l][r], dp_min[l][k] + dp_min[k+1][r] + s[r] - s[l-1]);
                    dp_max[l][r] = max(dp_max[l][r], dp_max[l][k] + dp_max[k+1][r] + s[r] - s[l-1]);
                }
            }
        }
        // 遍历所有长度为n的区间,得到最终结果
        int ans_min = INF, ans_max = 0;
        for (int i = 1; i <= n; ++i) {
            ans_min = min(ans_min, dp_min[i][i + n - 1]);
            ans_max = max(ans_max, dp_max[i][i + n - 1]);
        }
        // 输出结果
        cout << ans_min << endl;
        cout << ans_max << endl;
        return 0;
    }
    
    • 1

    信息

    ID
    1344
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者