由于这道题决策点的值并不打掉 所以要搞个平衡树上去(虽然暴力也可以过) 正好操作需求不大 可以直接用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';
}
}
本文探讨了使用平衡树和多集来解决特定问题的方法,特别是当决策点不涉及删除操作时。文章详细介绍了如何利用C++的STL库中的multiset进行高效操作,并对比了G++和C++的效率。通过实例展示了算法实现过程及优化策略。
276

被折叠的 条评论
为什么被折叠?



