关闭

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

13513人阅读 评论(0) 收藏 举报

还是斜率优化。还是很简单。略过。注意一下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
	//Initializaion
	for (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;
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:327139次
    • 积分:7190
    • 等级:
    • 排名:第3091名
    • 原创:419篇
    • 转载:14篇
    • 译文:0篇
    • 评论:32条
    文章分类
    最新评论