习题:Vasya and Maximum Profit(单调栈&DP)
题目
思路
对于一个区间\(l到r\),答案即为
\(\begin{aligned}val_{l,r}=&a*(r-l+1)-max_{i=l}^{r-1}(d_{i+1}-d_i)^2-\sum_{i=l}^rc_i\\=&a*r-a*(l-1)-max_{i=l}^{r-1}(d_{i+1}-d_i)^2-sum_r+sum_{l-1}\end{aligned}\)
\(val_{l,r}+a*(l-1)-sum_{l-1}=a*r-max_{i=l}^{r-1}(d_{i+1}-d_i)^2-sum_r\)
左边的很明显是固定的,只需要右边最大即可
考虑从n到1来扫,只需要用单调栈来优化即可
代码
#include<iostream>
using namespace std;
struct node
{
long long f;
long long maxx;
long long maxr;
};
int n,top;
long long a;
long long ans;
long long d[300005],f[300005],sum[300005];
node s[300005];
int main()
{
cin>>n>>a;
for(int i=1;i<=n;i++)
{
long long x;
cin>>d[i]>>x;
sum[i]=sum[i-1]+x;
f[i]=a*i-sum[i];
}
ans=max(a+sum[n-1]-sum[n],0ll);
s[++top]=(node){f[n],0,f[n]};
s[0].maxr=-(1ll<<60);
for(int i=n-1;i>=1;i--)
{
long long maxf=-(1ll<<60);
while(top&&d[i+1]-d[i]>=s[top].maxx)
{
maxf=max(maxf,s[top].f);
top--;
}
if(maxf!=-(1ll<<60))
{
top++;
s[top]=(node){maxf,d[i+1]-d[i],max(maxf-(d[i+1]-d[i])*(d[i+1]-d[i]),s[top-1].maxr)};
}
s[++top]=(node){f[i],0,max(f[i],s[top-1].maxr)};
ans=max(ans,s[top].maxr-a*i+a+sum[i-1]);
}
cout<<ans;
return 0;
}

浙公网安备 33010602011771号