zoukankan      html  css  js  c++  java
  • 斜率优化

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

    一.玩具装箱

    怕是斜率优化的入门题

    #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
  • 相关阅读:
    数学
    数学
    Computer Science
    数学
    Computer Science
    元学习
    数学
    数学
    数学
    数学
  • 原文地址:https://www.cnblogs.com/BriMon/p/9076933.html
Copyright © 2011-2022 走看看