B.最优购物 purchase
题目链接-B.最优购物 purchase
解题思路
滑动窗口问题,单调队列即可,只需要用双向队列deque
维护一个递增序列
具体步骤:
- 不断删除队尾的元素直至队尾对应的价格小于第 天 的价格
- 再把 做为一个新的决策入队
- 如果i - 队首下标>=d,说明队首元素过期,则弹出队首元素,经过一系列此操作后队首元素就是第 天要喝的可乐买时的最低价格
附上代码
//#pragma GCC diagnostic error "-std=c++11"
#include<bits/stdc++.h>
#define int long long
#define lowbit(x) (x &(-x))
#define endl '\n'
using namespace std;
const int INF=0x3f3f3f3f;
const int dir[4][2]={-1,0,1,0,0,-1,0,1};
const double PI=acos(-1.0);
const double e=exp(1.0);
const double eps=1e-10;
const int M=1e9+7;
const int N=1e5+5;
typedef long long ll;
typedef pair<int,int> PII;
typedef unsigned long long ull;
int a[N];
deque<int> q;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n,d,ans=0;
cin>>n>>d;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++){
while(q.size()&&a[q.back()]>=a[i])
q.pop_back();
q.push_back(i);
while(q.size()&&q.front()<=i-d)
q.pop_front();
ans+=a[q.front()];
}
cout<<ans<<endl;
return 0;
}