1 条题解
-
0
#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
- 上传者