【斜率优化DP】特别行动队

来源:互联网 发布:微信一键清理好友软件 编辑:程序博客网 时间:2024/05/18 00:11

还是斜率优化。还是很简单。略过。注意一下B的那一项是可以分离出来的,和i、j都是无关的,速度快点。这里没有给出实现。

但是C是不能分离的,分离出来,C是和分的数量有关的,就会方程必须增加一维。。。


#include <cstdio>#include <iostream>#include <algorithm>#include <string>typedef long long ll;#define max(a,b) (a>b?a:b)#define min(a,b) (a<b?a:b)long q[1000005];long n;long A;long B;long C;long fight[1000010];ll sum[1000010];ll f[1000010];long que[1000010];long l = 0;long r = 0;inline long getint(){      long ret = 0;      char tmp;      while (!isdigit(tmp = getchar()));      do {          ret = (ret << 3)+(ret << 1) + tmp - '0';      } while (isdigit(tmp = getchar()));      return ret;}  ll Calc(long j,long k){return f[j]-f[k]+A*(sum[j]*sum[j]-sum[k]*sum[k])-B*(sum[j]-sum[k]);}int main(){freopen("commando.in","r",stdin);freopen("commando.out","w",stdout);n = getint();A = -getint();scanf("%ld%ld",&B,&C);for (long i=1;i<n+1;++i){fight[i] = getint();sum[i] = sum[i-1]+(ll)fight[i];}//A < 0//Initializaionfor (long i=1;i<n+1;i++)f[i] = -0x7f7f7f7f;for (long i=1;i<n+1;i++){while (l<r&&Calc(q[l],q[l+1])<=2*A*sum[i]*(sum[q[l]]-sum[q[l+1]]))l++;long ch = q[l];long x=sum[i]-sum[ch];f[i] = f[ch] + A*x*x+x*B+C;while (l<r&&Calc(q[r-1],q[r])*(sum[q[r]]-sum[i])<=Calc(q[r],i)*(sum[q[r-1]]-sum[q[r]]))r--;q[++r] = i;}std::cout << f[n];return 0;}


原创粉丝点击