您的位置:首页 > 其它

bzoj3831 洛谷3572 little bird 单调队列优化dp

2018-03-11 21:47 387 查看
题意:
从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])第一个可以用单调队列优化,第二个?设体力消耗为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
);
}
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: