日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P3957-跳房子【单调队列,dp,二分】

發布時間:2023/12/3 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P3957-跳房子【单调队列,dp,二分】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

鏈接:
https://www.luogu.org/record/show?rid=7915892
這就是之前普及組的第四題…


大意

有n個格子,每個格子有價值。機器人有固定的跳躍距離d,用k個金幣改進的話,就可以讓跳躍距離在d-k到d+k之間,不過至少要往前跳1個單位長度,每次都必須跳到格子上。要求超過需要的價值求需要消耗的最少金幣。


解題思路

二分所需金幣數然后
dp,f[i]f[i]表示跳到第i個格子最大價值,然

f[i]=f[max:f[l]...f[r];]+c[i]f[i]=f[max:f[l]...f[r];]+c[i] ,這個簡單的方程就不解釋了,然后單調隊列維護 max:f[l]...f[r];max:f[l]...f[r];


代碼

#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,二分】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。