Bzoj 3831: [Poi2014]Little Bird
阿新 • • 發佈:2017-05-07
元素 eof ont pac color can 16px set 題目
3831: [Poi2014]Little Bird
題目大意:從1開始,跳到比當前矮的不消耗體力,否則消耗一點體力,每次詢問有一個步伐限制,求每次最少耗費多少體力
f[i]表示跳到i位置消耗的最小體力
從單調隊列中取數,維護的東西有三個
1.單調隊列的範圍維持在K以內
2.隊列尾部位置對應的答案與當前枚舉到的位置對應的答案相比,當前答案更優時(f[now]最小時),彈出尾元素
3.隊列尾部位置對應的答案與當前枚舉到的位置對應的答案相同時,比較當前位置的高度和隊尾位置的高度,隊尾元素較低的話,彈出尾元素
一系列維護之後,將當前點放入隊尾
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,m,q[1000010],H[1000010],f[1000010]; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&H[i]); scanf("%d",&m); int h,t; for(int j=1;j<=m;j++){ h=t=1; int k;scanf("%d",&k); memset(q,0,sizeof(q)); memset(f,0,sizeof(h)); q[t++]=1; for(int i=2;i<=n;i++){ while(h<t&&i>q[h]+k)h++; f[i]=f[q[h]]+(H[q[h]]>H[i]?0:1); while(h<t&&(f[q[t-1]]>f[i]||(f[q[t-1]]==f[i]&&H[q[t-1]]<=H[i])))t--; q[t++]=i; } printf("%d\n",f[n]); } }
Bzoj 3831: [Poi2014]Little Bird