斜率优化入门练习题, 不想写题解了
左转大仙博客, 然后你就能切了这道题哦
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
const int N = 100005;
const int M = 10005;
#define int long long
#define t1 vec[c[i]][vec[c[i]].size() - 1]
#define t2 vec[c[i]][vec[c[i]].size() - 2]
using namespace std;
int n, c[N], last[M], sum[N], f[N];
vector<int> vec[M];
template < typename T >
inline T read()
{
T x = 0, w = 1; char c = getchar();
while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * w;
}
double calc(int x, int y)
{
return 1.0 * (f[x - 1] - f[y - 1] + c[x] * (sum[x] * (sum[x] - 2) - sum[y] * (sum[y] - 2))) / (2.0 * c[x] * (sum[x] - sum[y]));
}
signed main()
{
n = read <int> ();
for(int i = 1; i <= n; i++)
c[i] = read <int> (), sum[i] = sum[last[c[i]]] + 1, last[c[i]] = i;
for(int i = 1; i <= n; i++)
{
while(vec[c[i]].size() >= 2 && calc(i, t1) >= calc(t1, t2))
vec[c[i]].pop_back();
vec[c[i]].push_back(i);
while(vec[c[i]].size() >= 2 && calc(t1, t2) < sum[i])
vec[c[i]].pop_back();
f[i] = f[t1 - 1] + c[i] * (sum[i] - sum[t1] + 1) * (sum[i] - sum[t1] + 1);
}
printf("%lld\n", f[n]);
return 0;
}
原文:https://www.cnblogs.com/ztlztl/p/12258678.html