[NOIP2017普及]跳房子

我太弱了。。。
单调队列优化DP+二分答案。

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include <ctime>
#include <set>
#include <map>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define go(i,k) for(int i=head[k],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
using namespace std;
typedef long long ll;
typedef double db;
const int inf=0x3f3f3f3f;
inline int rd() {
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
	return x*f;
}
const int N=500005;
int n,d,k,hd,tl,q[N],f[N],a[N],s[N],now;
bool ck(int g) {
	int mn=max(1,d-g),mx=d+g;
	hd=1,tl=0,now=0;
	memset(f,0,sizeof f);
	fo(i,1,n) {
		while(now<i&&s[now]<=s[i]-mn) {
			while(hd<=tl&&(f[q[tl]]<f[now]))tl--;
			if(f[now]==-inf) {now++;continue;}
			q[++tl]=now;
			now++;
		}
		while(hd<=tl&&(s[i]-s[q[hd]]>mx)) hd++;
		if(hd>tl) {f[i]=-inf;continue;}
		f[i]=f[q[hd]]+a[i];
		if(f[i]>=k) return 1;
	}
	return 0;
}
int main() {
#ifdef HSZ
	freopen(".in","r",stdin);
	freopen(".out","w",stdout);
#endif
	n=rd(),d=rd(),k=rd();
	int l=0,r,ans=-1;
	fo(i,1,n) s[i]=rd(),a[i]=rd();
	r=s[n];
	while(l<=r) {
		int mid=l+r>>1;
		if(ck(mid)) r=mid-1,ans=mid;
		else l=mid+1;
	}
	cout<<ans<<endl;
	return 0;
}
posted @ 2018-10-25 21:43  SWHsz  阅读(541)  评论(0编辑  收藏  举报