题意:
从1开始,跳到比当前矮的不消耗体力,否则消耗一点体力,每次询问有一个步伐限制,求每次最少耗费多少体力。
好久没发题解了,过去一段时间都在听别人讲题,自己没怎么写。所以本蒟蒻决定补一补之前该写的题。
一道单调队列优化dp
dp[i]表示跳到第i棵树上体力消耗的最小值
dp[i]=min(dp[j]+1) (i-k≤j<i )
dp[i]=min(dp[j]) (i-k≤j<i &&a[j]>a[i])
dp[i]=min(dp[j]) (i-k≤j<i &&a[j]>a[i])
第一个可以用单调队列优化,第二个?
设体力消耗为x,当前树高为y,那么<x,y>优于任何<x+1,y>
维护一个dp值单调递增,dp值相同时a单调递减的单调队列
粘一下我的代码吧qwq
#include <bits/stdc++.h>
using namespace std;
int n,a[1000010],m,k,q[1000010],h,t,dp[1000010];
void work()
{
q[1]=1;
h=t=1;
dp[1]=0;
for(int i=2;i<=n;i++)
{
while(h<=t&&i-q[h]>k)
h++;
dp[i]=dp[q[h]]+(a[q[h]]<=a[i]);
while(h<=t&&(dp[i]<dp[q[t]]||(dp[i]==dp[q[t]]&&a[i]>=a[q[t]])))
t--;
q[++t]=i;
}
printf("%d\n",dp[n]);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&m);
.
for(int i=1;i<=m;i++)
{
scanf("%d",&k);
work();
}
return 0;
}