DP比较显然,直接上斜率优化就好了。。
#include<iostream>
#include<cstdio>
#include<memory.h>
#include<cstdlib>
#include<math.h>
#define ll long long
#define q1 que[head]
#define q2 que[head+1]
#define t1 que[tail]
#define t2 que[tail-1]
#define maxn 1000005
using namespace std;
int i,j,n,head,tail,x[maxn],que[maxn];
ll sum[maxn],dp[maxn],a,b,c;
ll sqr(ll x) {return x*x;}
ll G(int i) {return dp[i]+a*sqr(sum[i])-b*sum[i];}
ll H(int i) {return a*sqr(sum[i])+b*sum[i]+c;}
ll get(int i)
{
while (tail>head&&2*a*sum[i]*(sum[q2]-sum[q1])<G(q2)-G(q1)) head++;
// printf("%d %d*\n",i,q1);
return -2*a*sum[i]*sum[q1]+G(q1)+H(i);
}
void ins(int i)
{
while (tail>head&&(G(i)-G(t1))*(sum[t1]-sum[t2])>(G(t1)-G(t2))*(sum[i]-sum[t1])) tail--;
que[++tail]=i;
}
int main()
{
freopen("1911.in","r",stdin);
scanf("%d",&n);
cin>>a>>b>>c;
sum[0]=dp[0]=0;
for (i=1;i<=n;i++)
{
scanf("%d",&x[i]);
sum[i]=sum[i-1]+(ll)x[i];
}
head=tail=1;que[1]=0;
for (i=1;i<=n;i++)
{
dp[i]=get(i);
ins(i);//printf("%I64d %I64d\n",dp[i],G(i));
}
cout<<dp[n];
}
本文介绍了一种使用斜率优化技巧解决动态规划问题的方法。通过具体实现代码展示了如何利用斜率优化来提高DP算法的效率,并给出了完整的C++代码示例。
1284

被折叠的 条评论
为什么被折叠?



