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


目录
相关文章
【LeetCode题目详解】(三)21.合并两个有序链表、141.环形链表、142.环形链表Ⅱ
【LeetCode题目详解】(三)21.合并两个有序链表、141.环形链表、142.环形链表Ⅱ
103 0
|
1月前
acwing 836 合并区间
acwing 836 合并区间
13 1
acwing 836 合并区间
|
3月前
|
算法 Java
LeetCode初级算法题:环形链表+排列硬币+合并两个有序数组java解法
LeetCode初级算法题:环形链表+排列硬币+合并两个有序数组java解法
54 0
|
5月前
|
算法 C++
【洛谷 P1090】[NOIP2004 提高组] 合并果子(贪心算法+哈夫曼编码+优先队列)
该编程题目要求设计算法,将不同种类的果子合并成一堆,使得消耗的体力最小。给定果子种类数`n`(1至10000)和每种果子的数量,需输出合并的最小体力值。使用优先队列(最小堆),每次取出两个数量最少的果子堆合并,并更新总体力消耗。样例输入为3种果子(1, 2, 9),输出最小体力耗费为15。提供的AC代码采用C++实现,通过优先队列优化合并顺序。
68 0
|
6月前
|
索引
【力扣刷题】回文链表、环形链表、合并两个有序链表
【力扣刷题】回文链表、环形链表、合并两个有序链表
37 0
|
6月前
|
JavaScript
线性dp之石子合并
线性dp之石子合并
|
6月前
代码随想录Day45 动态规划13 LeetCode T1143最长公共子序列 T1135 不相交的线 T53最大子数组和
代码随想录Day45 动态规划13 LeetCode T1143最长公共子序列 T1135 不相交的线 T53最大子数组和
58 0
|
人工智能
石子合并-区间dp
石子合并-区间dp
79 0
区间DP:合并石子
区间DP:合并石子
61 0