思路
首先暴力DP显然,可以得20分
加上一个前缀和优化,可以得到40分
然后上斜率优化
设(sum_i)为(sum_{1}^iP_i),(sump_i)为(sum_{1}^{i}P_i imes Pos_i)
则决策j优于决策i的条件可以表示为
[dp_j+C_t+pos_t imes(sum_t-sum_{j}) - (sump_t - sump_{j})<dp_i+C_t+pos_t imes(sum_t-sum_{i}) - (sump_t - sump_{i})
]
化简即可
这里贴上我认为写的不错的一篇题解其实是懒得写式子了
代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#define int long long
using namespace std;
int dp[1000010],n,c[1000010],p[1000010],pos[1000010],sum[1000010],summ[1000010];
int queue[1000010],h,t;
int T(int x){
return dp[x]+summ[x];
}
int S(int x){
return sum[x];
}
signed main(){
// freopen("6.in","r",stdin);
memset(dp,0x3f,sizeof(dp));
scanf("%lld",&n);
for(int i=1;i<=n;i++){
scanf("%lld %lld %lld",&pos[i],&p[i],&c[i]);
sum[i]=sum[i-1]+p[i];
summ[i]=summ[i-1]+p[i]*pos[i];
}
dp[0]=0;
// dp[1]=c[1];
for(int i=1;i<=n;i++){
while(h<t&&1.0*(T(queue[h+1])-T(queue[h]))/((S(queue[h+1])-S(queue[h])))<pos[i])
h++;
dp[i]=dp[queue[h]]+pos[i]*(sum[i]-sum[queue[h]])-(summ[i]-summ[queue[h]])+c[i];
while(h<t&&1.0*(T(i)-T(queue[t]))/((S(i)-S(queue[t])))<1.0*(T(queue[t-1])-T(queue[t]))/((S(queue[t-1])-S(queue[t]))))
t--;
queue[++t]=i;
}
printf("%lld
",dp[n]);
return 0;
}