题目链接:合并神犇
我们令 dp[i] 为前i个神犇最多留下的个数,last[i]为第i个留下的值。
考虑转移:
dp[i] = dp[j] + 1 ,subject to:sum[i]-sum[j]>=last[j]
所以可用单调队列优化。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int n,sum[N],dp[N],last[N],q[N],head,tail;
signed main(){
cin>>n;
for(int i=1;i<=n;i++) scanf("%lld",&sum[i]),sum[i]+=sum[i-1];
for(int i=1;i<=n;i++){
while(head<tail&&sum[i]>=sum[q[head+1]]+last[q[head+1]]) head++;
dp[i]=dp[q[head]]+1;
last[i]=sum[i]-sum[q[head]];
while(head<=tail&&sum[q[tail]]+last[q[tail]]>=sum[i]+last[i]) tail--;
q[++tail]=i;
}
cout<<n-dp[n];
return 0;
}