P1880 [NOI1995]石子合并
经典区间dp,破环成链,枚举新起点与新终点即可(i,i+n-1)
#include<bits/stdc++.h> using namespace std; #define lowbit(x) ((x)&(-x)) typedef long long LL; typedef pair<int,int> pii; const int INF = 0x3f3f3f3f; const int maxn = 205; int Max[maxn][maxn]; int Min[maxn][maxn]; int sum[maxn], buf[maxn]; void run_case() { int n; cin >> n; for(int i = 1; i <= n; ++i) { int t; cin >> buf[i]; buf[i+n] = buf[i]; } for(int i = 1; i <= n+n; ++i) sum[i] = sum[i-1] + buf[i]; for(int m = 1; m < n; ++m) { for(int i = 1, j = i + m; i < n+n && j < n+n; ++i, j = i+m) { Min[i][j] = INF; for(int k = i; k < j; ++k) { Max[i][j] = max(Max[i][j], Max[i][k] + Max[k+1][j] + sum[j] - sum[i-1]); Min[i][j] = min(Min[i][j], Min[i][k] + Min[k+1][j] + sum[j] - sum[i-1]); } } } int aMin = INF, aMax = -1; for(int i = 1; i <= n; ++i) { aMin = min(Min[i][i+n-1], aMin); aMax = max(aMax, Max[i][i+n-1]); } cout << aMin << "\n" << aMax; } int main() { ios::sync_with_stdio(false), cin.tie(0); cout.flags(ios::fixed);cout.precision(10); //int t; cin >> t; //while(t--) run_case(); cout.flush(); return 0; }