Files
python/TangDou/AcWing/Section/1068_dfs.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

56 lines
2.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 410; // 注意开双倍空间
int a[N]; // 原始数组
int s[N]; // 前缀和
int f[N][N]; // 最小得分,从i堆合并到j堆的最小代价
int g[N][N]; // 最大得分,从i堆合并到j堆的最大代价
int n, m;
// 搜索出l~r的最小得分
int dfs1(int l, int r) { // 求出最小得分
int &v = f[l][r]; // 利用C++特性,定义一个v,简化代码
if (l == r) return v = 0; // l==r时返回0
if (v) return v; // 已保存的状态不必搜索
int res = INF; // 初始值赋为最大值以求最小值
// 枚举l~r之间的每个可能k,之所以k∈[l,r),可以看下面的递推关系式dfs1(k+1,r)决定了k最大是r-1
for (int k = l; k < r; k++)
res = min(res, dfs1(l, k) + dfs1(k + 1, r));
return v = res + s[r] - s[l - 1]; // 记录状态
}
// 搜索出l~r的最大得分
int dfs2(int l, int r) { // 求出最大得分
int &v = g[l][r]; // 利用C++特性,定义一个v,简化代码
if (l == r) return v = 0; // 若初始值为0可省略该句
if (v) return v; // l==r时返回0
int res = 0; // 初始值设为0
for (int k = l; k < r; k++)
res = max(res, dfs2(l, k) + dfs2(k + 1, r));
return v = res + s[r] - s[l - 1]; // 记录状态
}
int main() {
scanf("%d", &n);
// 破环成链
for (int i = 1; i <= n; i++) scanf("%d", &a[i]), a[i + n] = a[i];
// 前缀和
for (int i = 1; i <= 2 * n; i++) s[i] = s[i - 1] + a[i];
// 搜索出1-2*n的最小得分
dfs1(1, 2 * n);
// 搜索出1-2*n的最大得分
dfs2(1, 2 * n);
int ans1 = INF, ans2 = 0;
for (int i = 1; i <= n; i++) {
ans1 = min(f[i][n + i - 1], ans1); // 选出最小答案
ans2 = max(g[i][n + i - 1], ans2); // 选出最大答案
}
printf("%d \n%d", ans1, ans2);
return 0;
}