题意:
小明为了变得越来越神,他给自己制定了
很明显的
设
其中
由于对于每一个
由于要让兴奋值最大,而
设
由于
所以
所以我们可以用一个指针直接从左到右扫一遍即可,第一个满足前提条件的就是最小的。
问题解决,本质是用一个单调队列维护
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m,hard[201010];
long long sum[201010],dp[201010];
int main()
{
freopen("Plan.in","r",stdin);
freopen("Plan.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&hard[i]);
for(int i=1;i<=n;i++)
{
long long x;
scanf("%lld",&x);
sum[i]=sum[i-1]+x;
}
memset(dp,-0x3f,sizeof(dp));
dp[0]=m;//初始化
for(int i=1,j=0;i<=n;i++)
{
while(dp[j]<hard[i])
j++;//类似的单调队列优化
dp[i]=max(dp[i],dp[j]-hard[i]+sum[i]-sum[j]);//DP
}
printf("%lld",dp[n]);
return 0;
}