只有前49分的7个点没RE,数组已经开大100倍了也不行(
RE记录
#include <cmath>
#include <iostream>
using namespace std;
/*
Красная Армия всех сильней.
*/
void pre() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#define DEBUG(A) cout << A << endl
#else
#define DEBUG(A)
#endif
}
#define N 2002000
#define down 0.9996
#define eps 1e-10
int n;
int w[N];
int d[N]; // i~i+1的距离
int dsum[N]; // d的前缀和,从山顶i + 1的距离,那么i~j的距离就是(dsum[j] - dsum[i])
int x1, x2; //全局最优解,显然一定是某棵树的下标
int ans; //全局最优答案
void sa() {
for (double T = 10000; T > eps; T *= down) {
int nx1, nx2;
nx1 = ((int)(x1 + (rand() * 2 - RAND_MAX) * T) % n) + 1;
nx2 = ((int)(x2 + (rand() * 2 - RAND_MAX) * T) % n) + 1;
if (nx1 > nx2) {
swap(nx1, nx2);
}
int nans = 0;
for (int i = 1; i <= nx1; i++) {
nans += (dsum[nx1] - dsum[i]) * w[i];
}
for (int i = nx1 + 1; i <= nx2; i++) {
nans += (dsum[nx2] - dsum[i]) * w[i];
}
for (int i = nx2 + 1; i <= n; i++) {
nans += (dsum[n + 1] - dsum[i]) * w[i];
}
int dans = nans - ans;
if (dans < eps) {
ans = nans;
x1 = nx1;
x2 = nx2;
} else {
if (exp(-dans / T) * RAND_MAX > rand()) {
ans = nans;
x1 = nx1;
x2 = nx2;
}
}
}
}
signed main() {
pre();
/*code here*/
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> w[i] >> d[i];
dsum[i + 1] = dsum[i] + d[i];
}
x1 = n / 3;
x2 = x1 * 2;
for (int i = 1; i <= x1; i++) {
ans += (dsum[x1] - dsum[i]) * w[i];
}
for (int i = x1 + 1; i <= x2; i++) {
ans += (dsum[x2] - dsum[i]) * w[i];
}
for (int i = x2 + 1; i <= n; i++) {
ans += (dsum[n + 1] - dsum[i]) * w[i];
}
sa();
cout << ans;
return 0;
}