专栏文章

题解:AT_arc128_c [ARC128C] Max Dot

AT_arc128_c题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miosgnk8
此快照首次捕获于
2025/12/03 00:24
3 个月前
此快照最后确认于
2025/12/03 00:24
3 个月前
查看原文
不妨设 xi=j=1ndjx_i = \sum_{j=1}^{n} d_j,那么问题可以改写成线性规划形式
CPP
maximize a[1] * d[1] + a[2] * d[2] + ... + a[n] * d[n]
such that
d[i] >= 0, i = 1, 2, ..., n
d[1] + d[2] + ... + d[n] <= m
n*d[1] + (n-1)*d[2] + ... + d[n] <= s
把问题对偶可以得到如下对偶线性规划
CPP
minimize mx[1] + sx[2]
such that
x[1], x[2] >= 0
x[1] + nx[2] >= a[1]
x[1] + (n-1)x[2] >= a[2]
...
x[1] + 1x[2] >= a[n]
这个线性规划问题若确定 x[1]x[1] 则最优解是很好算的,让这个最优解为 f(x[1])f(x[1]). 观察到 f(x)f(x)xx 单谷,三分即可。
CPP
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 5005;
int n, m, s;
ll a[N];
int p[N];
double d[N];

double val (double X) {
  double ans = 0;
  for (int i = 1; i <= n; ++i) {
    ans = max(ans, (double)(a[i] - X) / (n - i + 1));
  }
  return s * ans + m * X;
}

/*
*/
int main() {
  cin >> n >> m >> s;
  for (int i = 1; i <= n; ++i) {
    cin >> a[i];
    p[i] = i;
  }
  
  
  for (int i = n; i >= 1; --i)
    a[i] += a[i + 1];
    
    
  double l = 0, r = 1e10, ans = 0;
  while (r - l > 1e-6) {
    double fr = (l + 2 * r) / 3, fl = (2 * l + r) / 3;
    if (val(fl) < val(fr)) r = fr;
    else l = fl;
  }
  cout << fixed << setprecision(12) << val(l);
  return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...