目录
显示
题目链接
https://www.luogu.org/problem/P3572
题解
按照正常的状态转移方式,对于一个点 \(i\),我们枚举能跳到这个点的点 \(j\) 来更新答案。
这么做的复杂度是 \(O(qn^2)\) 的,需要优化。
我们发现本题的转移有单调性,考虑使用单调队列优化 DP。这样便把复杂度降到了 \(O(qn)\)。
#include <cstdio> #include <algorithm> int a[1000005],que[1000005],f[1000005]; int main() { int n,q; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); scanf("%d",&q); while(q--) { int x,h,t; scanf("%d",&x); h=t=1,que[1]=1; for(int i=2;i<=n;i++) { while(h<=t&&i-que[h]>x) h++; if(a[que[h]]>a[i])f[i]=f[que[h]]; else f[i]=f[que[h]]+1; while(h<=t&&(f[que[t]]>f[i]||(f[que[t]]==f[i]&&a[que[t]]<=a[i]))) t--; que[++t]=i; } printf("%d\n",f[n]); } return 0; }