Luogu4983 忘情

Luogu4983 忘情

定义序列 \(x_1,\ x_2,\ \cdots,\ x_n\) 的值为 \(\frac{((\displaystyle\sum_{k=1}^nx_k\times \bar x) + \bar x)^2}{\bar x^2}\)

给定一段序列 \(a_1,\ a_2,\ \cdots,\ a_n\) ,将它分成 \(m\) 段,使每段值的和最小,求这个最小值

\(m\leq n\leq10^5,\ 1\leq a_i\leq1000\)

wqs二分+斜率优化


首先考虑不限制段数,斜率优化即可

原式 \(=(1+\displaystyle\sum_{k=1}^nx_i)^2\)

\(s_i=\displaystyle\sum_{k=1}^ia_k\)

列出 \(dp\) 方程 \[f_i=\displaystyle\min_{j<i}\{f_j+(s_i-s_j+1)^2\}\]

去掉 \(\min\),套路化简得 \[f_j=(2s_i+1)s_j+f_i-s_i^2-2s_i-1\]

然后用单调队列维护下凸包~

然后考虑如何限制段数

感性地理解或者打表观察或者严格的数学证明可以发现:如果我们给每个 \(f_i\) 值都强行加上一个增量 \(w\),因为要最小化 \(f_i\),那么 \(w\) 越大,总段数就会越少

所以我们可以二分这个重物 \(val\),斜率优化做一遍 \(dp\),同时记录一下划分段数 \(c_i\),然后判断划分的总段数\(c_n\)\(m\) 的大小关系。如果 \(cnt_n>m\) 就说明 \(val\) 不够大,要调大。

时间复杂度 \(O(n\log w)\)

代码

#include <bits/stdc++.h>
using namespace std;

typedef double db;
typedef long long ll;
const int maxn = 1e5 + 10;
int n, m, c[maxn], q[maxn]; ll s[maxn], f[maxn];

ll sqr(ll x) { return x * x; }
db slope(int x, int y) {
  return db(f[x] - f[y] + sqr(s[x]) - sqr(s[y])) / db(s[x] - s[y]);
}

bool check(ll x) {
  int l = 1, r = 1; q[1] = 0;
  for (int i = 1; i <= n; i++) {
    while (l < r && slope(q[l], q[l + 1]) < 2.0 * (s[i] + 1)) l++;
    f[i] = f[q[l]] + sqr(s[i] - s[q[l]] + 1) + x, c[i] = c[q[l]] + 1;
    while (l < r && slope(q[r - 1], q[r]) > slope(q[r], i)) r--;
    q[++r] = i;
  }
  return c[n] > m;
}

int main() {
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; i++) {
    scanf("%lld", s + i), s[i] += s[i - 1];
  }
  ll l = 0, r = sqr(s[n]) + s[n], mid, res;
  while (l < r) {
    check(mid = l + r >> 1) ? l = mid + 1 : r = res = mid;
  }
  check(res);
  printf("%lld", f[n] - 1ll * res * m);
  return 0;
}

转载于:https://www.cnblogs.com/Juanzhang/p/10344613.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值