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; }