Acwing 1068 环形石子合并

简介: 笔记

环形石子合并


题意

将 n 堆石子绕圆形操场排放,现要将石子有序地合并成一堆。


规定每次只能选相邻的两堆合并成新的一堆,并将新的一堆的石子数记做该次合并的得分。


请编写一个程序,读入堆数 n 及每堆的石子数,并进行如下计算:


选择一种合并石子的方案,使得做 n−1 次合并得分总和最大。

选择一种合并石子的方案,使得做 n−1 次合并得分总和最小。


思路

将 n 堆石子按下列方式摆放:1   2   3   . . .   n − 1n  


将一般的石子合并扩展为长度为 2∗n 的石子合并 最后求最值的时候遍历每个长度为 n 的区间即可


代码

#include <bits/stdc++.h>
//#define int long long
#define INF 0x3f3f3f3f
#define mod 1000000007
#define endl '\n'
#define rep(i, st, ed) for (int (i) = (st); (i) <= (ed);++(i))
#define pre(i, ed, st) for (int (i) = (ed); i >= (st);--(i))
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline int lowbit(int x) { return x & -x; }
const int N = 500;
int n;
int a[N];
int f[N][N];
int g[N][N];
int sum[N];
void solve() {
  cin >> n;
  rep(i, 1, n) {
    cin >> a[i];
    a[i + n] = a[i];
  }
  rep(i, 1, 2 * n)sum[i] = sum[i - 1] + a[i];
  for (int i = 2; i <= n; ++i) { // 枚举区间长度
    for (int j = 1; j + i - 1 <= 2 * n; ++j) { // 枚举左端点
      int l = j, r = j + i - 1;
      f[l][r] = INF;
      g[l][r] = -INF;
      for (int k = l; k < r; ++k) {
        f[l][r] = min(f[l][r], f[l][k] + f[k + 1][r] + sum[r] - sum[l - 1]);
        g[l][r] = max(g[l][r], g[l][k] + g[k + 1][r] + sum[r] - sum[l - 1]);
      }
    }
  }
  int minn = INF, maxn = -INF;
  for (int i = 1; i <= n; ++i) {
    minn = min(minn, f[i][i + n - 1]);
    maxn = max(maxn, g[i][i + n - 1]);
  }
  cout << minn << endl << maxn << endl;
}
signed main() {
  // int t; cin >> t;
  // while (t--)
    solve();
  return 0;
}


目录
相关文章
|
5月前
【LeetCode题目详解】(三)21.合并两个有序链表、141.环形链表、142.环形链表Ⅱ
【LeetCode题目详解】(三)21.合并两个有序链表、141.环形链表、142.环形链表Ⅱ
73 0
|
6月前
|
算法
【Leetcode-70.爬楼梯 -88.合并两个有序数组】
【Leetcode-70.爬楼梯 -88.合并两个有序数组】
19 0
|
4月前
【每日一题Day192】LC1033移动石子直到连续 | 分类讨论 贪心
【每日一题Day192】LC1033移动石子直到连续 | 分类讨论 贪心
17 0
|
9月前
1274:【例9.18】合并石子
1274:【例9.18】合并石子
|
10月前
|
人工智能
石子合并-区间dp
石子合并-区间dp
51 0
|
10月前
区间DP:合并石子
区间DP:合并石子
41 0
|
11月前
|
人工智能 算法 C++
每日算法系列【LeetCode 1031】两个非重叠子数组的最大和
每日算法系列【LeetCode 1031】两个非重叠子数组的最大和
(归并排序)AcWing 788. 逆序对的数量
(归并排序)AcWing 788. 逆序对的数量
56 0
|
C++ Python
约瑟夫环——公式法——附LeetCode—剑指offer题目—剑指 Offer 62. 圆圈中最后剩下的数字
约瑟夫环——公式法——附LeetCode—剑指offer题目—剑指 Offer 62. 圆圈中最后剩下的数字
约瑟夫环——公式法——附LeetCode—剑指offer题目—剑指 Offer 62. 圆圈中最后剩下的数字
牛客-合并回文子串(区间DP)
牛客-合并回文子串(区间DP)
157 0