合并神犇

题目链接:合并神犇


我们令 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;
}
发布了579 篇原创文章 · 获赞 242 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/104293914