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

 

posted @ 2023-12-20 02:49  JMXZ  阅读(15)  评论(0)    收藏  举报