[POJ3017] Cut the Sequence && 单调队列

由于这道题决策点的值并不打掉 所以要搞个平衡树上去(虽然暴力也可以过) 正好操作需求不大 可以直接用multiset搞过去 还有就是G++的STL效率低可能超时 C++快的多

#include<cstdio>
#include<cstring>
#include<deque>
#include<queue>
#include<algorithm>
#include<set>
#include<iostream>
#define MAXN 100000
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
LL d[MAXN+10];
multiset <int> S;
LL A[MAXN+10], sum[MAXN+10];
deque <int> q;
int main()
{
	LL n, K;
	while(scanf("%lld%lld", &n, &K) == 2)
	{
		S.clear(); q.clear();
		bool f = false;
		for(int i = 1; i <= n; i++) 
		{
			scanf("%lld", &A[i]);
			sum[i] = sum[i-1] + A[i];
			if(A[i] > K)
				f = true;
		}
		if(f) {
			cout << "-1\n";
			continue;
		}
		int des = 0;
		for(int i = 1; i <= n; i++)
		{
			while(sum[i] - sum[des] > K) ++des;
			while(!q.empty() && q.front() <= des)
			{
				int F = q.front(); q.pop_front();
				if(!q.empty()) S.erase(d[F] + A[q.front()]);
			}
			while(!q.empty() && A[q.back()] <= A[i])
			{
				int B = q.back(); q.pop_back();
				if(!q.empty()) S.erase(d[q.back()] + A[B]);
			}
			if(!q.empty()) S.insert(d[q.back()] + A[i]);
			q.push_back(i);
			d[i] = d[des] + A[q.front()];
			if(S.size()) d[i] = min(d[i], (LL)(*(S.begin())));
		}
		cout << d[n] << '\n';
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值