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;
}
View Code

 

posted @ 2020-02-23 11:20  GRedComeT  阅读(137)  评论(0编辑  收藏  举报