P3957-跳房子【单调队列,dp,二分】
生活随笔
收集整理的這篇文章主要介紹了
P3957-跳房子【单调队列,dp,二分】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前言
鏈接:
https://www.luogu.org/record/show?rid=7915892
這就是之前普及組的第四題…
大意
有n個格子,每個格子有價值。機器人有固定的跳躍距離d,用k個金幣改進的話,就可以讓跳躍距離在d-k到d+k之間,不過至少要往前跳1個單位長度,每次都必須跳到格子上。要求超過需要的價值求需要消耗的最少金幣。
解題思路
二分所需金幣數然后
dp,f[i]f[i]表示跳到第i個格子最大價值,然
后
代碼
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; int f[500001],x[500001],c[500001],q[500001]; int n,d,k,l,r,mid; bool answer() {memset(f,-1,sizeof(f));//初始化f[0]=0;int head=1,tail=0,j=0;int farst=d+mid,sd=max(1,d-mid);//前后跳躍距離for (int i=1;i<=n;i++){while (x[j]+sd<=x[i])//可以跳到改格{while (head<=tail&&f[j]>=f[q[tail]]) tail--;q[++tail]=j;j++;//加入隊列并維護}while (head<=tail&&x[q[head]]+farst<x[i]) head++;//將已經無法跳到的退出if (head<=tail&&f[q[head]]!=-2333333) f[i]=f[q[head]]+c[i];else f[i]=-2333333;//密鑰,表示無法到達if (f[i]>=k) return 1;//已經可以退出}return 0; } int main() {scanf("%d%d%d",&n,&d,&k);for (int i=1;i<=n;i++)scanf("%d%d",&x[i],&c[i]);l=1;r=x[n];while (l<=r)//二分{mid=(l+r)/2;if (answer()) r=mid-1;else l=mid+1;}if (l>x[n]) printf("-1");else printf("%d",l); }總結
以上是生活随笔為你收集整理的P3957-跳房子【单调队列,dp,二分】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 逗鹅冤是什么意思 网络流行语逗鹅冤是什么
- 下一篇: 冒险岛怪物公园怎么去