P3957 [NOIP2017 普及组] 跳房子
单调队列优化dp + 二分答案
#include<bits/stdc++.h> using namespace std; #define N 500005 #define inf 0x3f3f3f3f #define LL long long int n,d,k; int x[N],v[N]; int q[N]; LL dp[N]; bool check(int cost){ memset(dp,0xcf,sizeof(dp)); dp[0]=0; int l=1,r=0; int lpos=max(1,d-cost); int rpos=d+cost; int cur=0; for(int i=1;i<=n;++i){ while(cur<i && x[i]-x[cur]>=lpos) { while(l<=r&&dp[cur]>=dp[q[r]])--r; q[++r]=cur; ++cur; } while(l<=r&&x[i]-x[q[l]]>rpos) ++l; if(l<=r) dp[i]=dp[q[l]]+v[i]; //cout<<dp[i]<<" "<<i<<" "<<l<<" "<<r<<endl; if(dp[i]>=k) return true; } // puts(""); return false; } int main(){ //freopen("1.in","r",stdin); scanf("%d%d%d",&n,&d,&k); for(int i=1;i<=n;++i) scanf("%d%d",&x[i],&v[i]); int ans=-1; int l=0,r=x[n]; while(l<=r){ int mid=(l+r)>>1; if(check(mid)){ ans=mid; r=mid-1; }else l=mid+1; } // check(0); printf("%d\n",ans); return 0; }

浙公网安备 33010602011771号