标签:href 最小花费 仓库 \n long inline head algo pac
考虑用dp[i]表示把前i个地点的物品全部安置好的最小花费。因为物品只能往下运,所以当前这个位置必须建仓库,dp方程很好想:
\[dp[i] = min_{j=1}^{i-1}\{dp[j] + \sum_{k=j+1}^{i-1} p[k] * (x[i] - x[k])\} + c[i]\]
用\(sum[n]\)表示\(\sum_{i=1}^np[i]\),\(ssum[n]\)表示\(\sum_{i=1}^np[i] * x[i]\)
之后把式子变个型套斜率优化就好了。得到:
\(\frac{dp[p]-dp[q]+ssum[p]-ssum[q]}{sum[p]-sum[q]} < x[i]\)时,q比p优。
因为这个x[i]是单调递增的,所以不用考虑特别多,套斜率优化即可。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar(‘\n‘)
#define pr pair<int,int>
#define mp make_pair
#define fi first
#define sc second
using namespace std;
typedef long long ll;
const int M = 1000005;
const int N = 10000005;
ll read()
{
ll ans = 0,op = 1;char ch = getchar();
while(ch < ‘0‘ || ch > ‘9‘) {if(ch == ‘-‘) op = -1;ch = getchar();}
while(ch >=‘0‘ && ch <= ‘9‘) ans = ans * 10 + ch - ‘0‘,ch = getchar();
return ans * op;
}
struct node
{
ll x,p,c;
}a[M];
ll sum[M],ssum[M],dp[M],n,q[M],head,tail;
double slope(ll p,ll q)
{
return (double)((dp[p]-dp[q]+ssum[p]-ssum[q]) / (sum[p]-sum[q]));
}
int main()
{
n = read(),head = tail = 1;
rep(i,1,n) a[i].x = read(),a[i].p = read(),a[i].c = read();
rep(i,1,n) sum[i] = sum[i-1] + a[i].p,ssum[i] = ssum[i-1] + a[i].x * a[i].p;
rep(i,1,n)
{
while(head < tail && slope(q[head],q[head+1]) < a[i].x) head++;
dp[i] = dp[q[head]] + (sum[i] - sum[q[head]]) * a[i].x + ssum[q[head]] - ssum[i] + a[i].c;
while(head < tail && slope(q[tail-1],q[tail]) > slope(q[tail],i)) tail--;
q[++tail] = i;
}
printf("%lld\n",dp[n]);
return 0;
}
标签:href 最小花费 仓库 \n long inline head algo pac
原文地址:https://www.cnblogs.com/captain1/p/10153401.html