[BZOJ 3831]Little Bird
单调队列水体……然而我这蒟蒻仍然WA一墙
这个题本质是一个动态规划,然后我们发现取区间递推最小值这个任务可以交给单调队列君来做~不过优先级似乎是一个问题……
优先级直接按照递推值来搞即可,递推值一样的话才按照高度比。因为就算递推值比较小但高度会带来额外影响,也不过是1,这样撑死也不会使答案更差
但凡是单调队列的题,都会有神秘细节,这题也不例外……顺便说一下这题不要傻乎乎的用pair
代码:
/**************************************************************
Problem: 3831
User: danihao123
Language: C++
Result: Accepted
Time:11596 ms
Memory:16228 kb
****************************************************************/
#include <cstdio>
#include <algorithm>
#include <queue>
#include <deque>
using namespace std;
const int maxn=1e6+1;
int D[maxn],f[maxn];
bool d_cmp(int x,int y){
if(f[x]==f[y])
return D[x]<D[y];
else
return f[x]>f[y];
}
struct DQueue{
deque<int> D;
queue<int> Q;
void push(int x){
Q.push(x);
while(!D.empty() && d_cmp(D.back(),x))
D.pop_back();
D.push_back(x);
}
int top(){
return D.front();
}
void pop(){
if(D.front()==Q.front())
D.pop_front();
Q.pop();
}
int size(){
return Q.size();
}
void clear(){
while(!Q.empty())
Q.pop();
D.clear();
}
};
DQueue hhh;
int main(){
register int i,temp,ans;
int n,Q,k;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&D[i]);
scanf("%d",&Q);
while(Q--){
scanf("%d",&k);
hhh.push(1);
f[1]=0;
for(i=2;i<=n;i++){
while(hhh.size()>k)
hhh.pop();
temp=hhh.top();
f[i]=f[temp]+(D[temp]<=D[i]);
hhh.push(i);
}
printf("%d\n",f[n]);
hhh.clear();
}
return 0;
}
[BZOJ 2442]修剪草坪
单调队列优化DP……
bi了doge了……现在才能学会一些简单的单调队列优化DP
代码: