斜率优化 & 凸包

 

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 300010;
int n, s;
typedef long long LL;
LL t[N], c[N], f[N], q[N];

int main()
{
    cin >> n >> s;
    for(int i = 1; i <= n; i ++)
    {
        cin >> t[i] >> c[i];
        t[i] += t[i - 1];
        c[i] += c[i - 1];
    }
    
    int hh = 0, tt = 0;
    
    for(int i = 1;i <= n;i ++)
    {
        int l = hh, r = tt;
        while(l < r)
        {
            int mid = l + r >> 1;
            if((f[q[mid + 1]] - f[q[mid]]) > (t[i] + s) * (c[q[mid + 1]] - c[q[mid]])) r = mid;
            else l = mid + 1;
        }
        
        int j = q[r] ;
        f[i] = f[j] - (t[i] + s) * c[j] + t[i] * c[i] + s * c[n];
        while(hh < tt && (double)(f[q[tt]] - f[q[tt - 1]]) * (c[i] - c[q[tt]]) >= (double)(f[i] - f[q[tt]]) * (c[q[tt]] - c[q[tt - 1]])) tt --;
        q[++tt] = i;
    }
    
    cout<<f[n]<<endl;
    
}

运输小猫:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010, M = 100010, P = 110;
typedef long long LL;
int n, m, p;
LL d[N], t[N], a[N], s[N];
LL f[P][M];
int q[M];

LL get_y(int k, int j)
{
    return f[j - 1][k] + s[k];
}

int main()
{
    ios :: sync_with_stdio(false);
    cin>>n>>m>>p;
    for(int i = 2; i <= n; i ++)
    {
        cin>>d[i];
        d[i] += d[i - 1];
    }
    
    for(int i = 1;i <= m; i ++)
    {
        int h;
        cin >> h >> t[i];
        a[i] = t[i] - d[h];
    }
    
    sort(a + 1, a + m + 1);
    
    for(int i = 1;i <= m; i ++) s[i] = s[i - 1] + a[i];
    
    memset(f, 0x3f, sizeof f);
    for(int i = 0; i <= p; i ++) f[i][0] = 0;
    
    for(int j = 1; j <= p; j++)
    {
        int hh = 0, tt = 0;
        q[0] = 0;
        
        for(int i = 1; i <= m; i++)
        {
            while(hh < tt && (get_y(q[hh + 1], j) - get_y(q[hh], j)) <= a[i] * (q[hh + 1] - q[hh])) hh++;
            int k = q[hh];
            f[j][i] = f[j-1][k] - a[i] * k + s[k] + a[i] * i - s[i];
            while(hh < tt && (get_y(q[tt], j) - get_y(q[tt - 1], j)) * (i - q[tt]) >= (get_y(i, j) - get_y(q[tt], j)) * (q[tt] - q[tt - 1])) tt--;
            q[++tt] = i;
        }
    }
    
    cout<<f[p][m]<<endl;
    
}
原文地址:https://www.cnblogs.com/longxue1991/p/12845640.html