luogu P4544 [USACO10NOV]Buying Feed G 斜率优化dp 双层?

#include<map>
#include<queue>
#include<time.h>
#include<limits.h>
#include<cmath>
#include<ostream>
#include<iterator>
#include<set>
#include<stack>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=505;
const int M=10005;
#define int long long
int k,e,n;
int f[N][M];
int q[M],tt,hh;
struct node
{
    int x,f,c;
} a[N];
bool cmp(node a,node b)
{
    return  a.x<b.x;
}
//在第i个点 有j原料
//f[i,j]=min{f[i-1,k] + k * k (x[i] - x[i-1])  + (j-k)* c[i]
//f[i,j]=f[i-1,k] + k * k (x[i] - x[i-1])-k*c[i] + j*c[i]
int calc(int p,int x)
{
    return f[p-1][x]+x*x*(a[p].x-a[p-1].x)-a[p].c*x;
}
signed main()
{
    memset(f,0x3f,sizeof f);
    f[0][0]=0;
    cin>>k>>e>>n;
    for(int i=1; i<=n; i++)
        cin>>a[i].x>>a[i].f>>a[i].c;
    sort(a+1,a+1+n,cmp);
    for(int i=1; i<=n; i++)
    {
        hh=1,tt=1;
        q[1]=q[0]=0;;
        for(int j=0; j<=k; j++)
        {
            while(hh<tt&&calc(i,q[tt-1])>calc(i,j))
                tt--;
            while(hh<tt&&q[hh]+a[i].f<j)
                hh++;
            q[tt++]=j;
            f[i][j]=calc(i,q[hh])+a[i].c*j;
        }
    }
    cout<<f[n][k]+k*k*(e-a[n].x)<<endl;
    return 0;
}

 

posted @ 2020-06-04 16:15  晴屿  阅读(153)  评论(0编辑  收藏  举报