P4544 [USACO10NOV] Buying Feed G
/* 约翰开车来到镇上,他要带KK吨饲料回家。运送饲料是需要花钱的,如果他的车上有XX吨饲料,每公里就要花费X2X2元,开车D公里就需要D×X2D×X2元。约翰可以从NN家商店购买饲料,所有商店都在一个坐标轴上,第ii家店的位置是XiXi,饲料的售价为每吨CiCi元,库存为FiFi。 约翰从坐标X=0X=0开始沿坐标轴正方向前进,他家在坐标X=EX=E上。为了带KK吨饲料回家,约翰最少的花费是多少呢?假设所有商店的库存之和不会少于KK。 E>Xi f[i][j] 到i店 在1-i已经买了j吨 f[i][j]=min(f[i][j],f[i-1][k]+(dis[i]-dis[i-1])*k^2+(j-k)*w[i]); (k<=f[i-1]) O(n*k^2) f[i][j]=min(f[i][j],f[i-1][k]+(dis[i]-dis[i-1])*k^2-k*w[i])+j*w[i] ; f[0][0]=0; f[][]=inf ans=f[n][k]+(E-xn)*k^2 至于i k有关 单调队列优化k 但因为库存有限 所以+特判 O[n*k] */ /* 2 5 3 3 1 2 4 1 2 1 1 1 9 */ #include<cstdio> #include<iostream> #include<algorithm> #include<cmath> #include<string.h> #include<queue> #include<vector> #include<bits/stdc++.h> typedef long long ll; #define ddd printf("-----------------------\n"); using namespace std; const int maxn=1e1 +10; const int mod=998244353; const int inf=0x3f3f3f3f; //#define int long long ll n,f[510][10010],E,k,q[10010]; struct node{ int x,f,c; bool operator < (const node &cmp)const{ return x<cmp.x; } }a[510]; ll cal(int p,int k){ return f[p-1][k]+(ll)(a[p].x-a[p-1].x)*k*k-(ll)k*a[p].c; } signed main() { ios::sync_with_stdio(false); 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); //for(int i=1;i<=n;i++) cout<<a[i] memset(f,inf,sizeof(f));f[0][0]=0; for(int i=1;i<=n;i++) { int head=1,tail=0;q[++tail]=0; for(int j=0;j<=k;j++) { while(head<=tail && cal(i,q[tail])>cal(i,j)) tail--; while(head<=tail && q[head]+a[i].f<j) head++; q[++tail]=j; f[i][j]=cal(i,q[head])+(ll)j*a[i].c; } } ll ans=f[n][k]+(ll)(E-a[n].x)*k*k; cout<<ans<<'\n'; return 0; }