斜率优化 一.玩具装箱 二.特别行动队 三.仓库建设

斜率优化这个玄学的东西, 其实都是模板,至少用单调队列维护时是这样的...

怕是斜率优化的入门题

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
#define int long long

int n, L;

int c[50005], sum[50005];

int f[50005];

double abss(double a)
{
    return a < 0 ? -a : a;
}

int A(int i)
{
    return sum[i] + i;
}

int B(int i)
{
    return A(i) + L + 1;
}

int X(int i)
{
    return B(i);
}

int Y(int i)
{
    return B(i) * B(i) + f[i];
}

int G(int i)
{
    return A(i);
}

double slope(int a, int b)
{
    return ((double)(Y(b) - Y(a)) / (double)(X(b) - X(a)));
}

int q[50005], l = 1, r = 1;


signed main()
{
    cin >> n >> L;
    
    for(register int i = 1 ; i <= n ; i ++)
    {
        scanf("%lld", &c[i]);
        sum[i] = sum[i-1] + c[i];
    }
    
    for(register int i = 1; i <= n ; i ++) 
    {
        while(l < r && slope(q[l], q[l+1]) < G(i) * 2) l++;
        int j = q[l];
        f[i] = Y(j) - 2 * G(i) * X(j) + A(i) * A(i);
        while(l < r && slope(q[r-1], q[r]) > slope(q[r-1], i)) r--;
        q[++r] = i;
    }
    
    printf("%lld
", f[n]);
    
    return 0;
}
zZhBr

二.特别行动队

其实也特别水

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define int long long

int n, a, b, c;
int sum[1000010];

int q[1000011], l, r;

int f[1000010];//考虑到第i个士兵的最大战斗力.
               //f[i] = f[i-1], f[i] = max(f[j] + a*(sum[i] - sum[j])^2 + b*(sum[i]-sum[j])+c);
               //f[i] = Y(i) - G(i) * X(j) + D;
               //X(i) = sum[i];
               //Y(i) = f[i] - b * sum[i] + a * sum[i] ^ 2;
               //G(i) = 2 * a * sum[i];
               //D = a * sum[i]^2 + b * sum[i] + c;

int G(int i)
{
    return 2 * a * sum[i];
}

int X(int i)
{
    return sum[i];
}

int Y(int i)
{
    return f[i] - b * sum[i] + a * sum[i] * sum[i];
}

int D(int i)
{
    return a * sum[i] * sum[i] + b * sum[i] + c;
}

double slope(int a, int b)
{
    return((double)(Y(b) - Y(a)) / (double)(X(b) - X(a)));
}


signed main()
{
    cin >> n >> a >> b >> c;
    
    for(register int i = 1 ; i <= n ; i ++)
    {
        int t ;
        scanf("%lld", &t);
        sum[i] = sum[i-1] + t;
    }
    
    for(register int i = 1 ; i <= n ; i ++)
    {
        
        while(l < r && slope(q[l], q[l+1]) > G(i)) l++;
        int j = q[l];
        f[i] = Y(j) - G(i) * X(j) + D(i);
        while(l < r && slope(q[r-1], q[r]) <=slope(q[r], i)) r--;
        q[++r] = i;
        //f[i] = max(f[i], f[i-1]);
    }
    
    cout << f[n];
    return 0;
    
}
zZhBr

三.仓库建设

水的不行

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define maxn 1000010
#define int long long

int n, x[maxn], p[maxn], c[maxn];
int sum[maxn], s[maxn];

int f[maxn]; 

inline int G(int i)
{
    return x[i];
}

inline int X(int i)
{
    return sum[i];
}

inline int D(int i)
{
    return c[i] - s[i] + x[i] * sum[i];
}

inline int Y(int i)
{
    return f[i] + s[i];
}

inline double slope(int a, int b)
{
    return ((double)(Y(b) - Y(a)) / (double)(X(b) - X(a)));
}

int q[maxn], l, r;


signed main() 
{
    cin >> n;
    for (int i = 1; i <= n; i++){
        scanf("%lld%lld%lld", &x[i], &p[i], &c[i]);
        sum[i] = sum[i-1] + p[i];
        s[i] = s[i-1] + x[i] * p[i];
        f[i] = 0x7f7f7f7f;
    }
    
    for (int i = 1; i <= n; i++){
        while (l < r && slope(q[l], q[l+1]) < G(i)) l++;
        int j = q[l];
        f[i] = Y(j) - G(i) * X(j) + D(i);
        while(l < r && slope(q[r-1], q[r]) > slope(q[r-1], i)) r--;
        q[++r] = i;
    }
    
    cout << f[n];
    return 0;
}
zZhBr