[NOI1995]石子合併 - 洛谷P1880
阿新 • • 發佈:2020-08-07
題目
https://www.luogu.com.cn/problem/P1880
CODE
區間DP
環 -> 鏈
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <queue> #include <string> #include <cstring> #include <map> #include <stack> #include <set> using namespace std; int n, a[101], sum[201], dps[201][201], dpb[201][201]; int main(){ scanf("%d", &n); memset(dps, 0x3f3f3f, sizeof(dps)); memset(dpb, -1, sizeof(dpb)); for(int i = 1; i <= n; i++){ scanf("%d", &a[i]); dps[i][i] = 0; dpb[i][i] = 0; sum[i] = sum[i - 1] + a[i]; } for(int i = 1; i <= n; i++){ dps[i + n][i + n] = 0; dpb[i + n][i + n] = 0; sum[i + n] = sum[i + n - 1] + a[i]; } for(int len = 1; len <= n; len++){ for(int i = 1; i + len <= 2 * n; i++){ int ends = i + len - 1; for(int j = i; j <= ends-1; j++){ dps[i][ends] = min(dps[i][ends], dps[i][j] + dps[j+1][ends] + sum[ends] - sum[i - 1]); dpb[i][ends] = max(dpb[i][ends], dpb[i][j] + dpb[j+1][ends] + sum[ends] - sum[i - 1]); } } } int minn = 1e9+10, maxn = -1; for(int i = 1; i <= n; i++){ minn = min(dps[i][n+i-1], minn); maxn = max(dpb[i][n+i-1], maxn); } printf("%d\n%d\n", minn, maxn); return 0; }