P3957 [NOIP2017 普及组] 跳房子(青春版代码)

[NOIP2017 普及组] 跳房子 - 洛谷

核心思路

单调队列优化dp

顺序

先让合法答案入队

再删去越界答案

判断非空 后 求 答案

一个答案合法 当且仅当 l <= dis <= r

调了n久,找题解调。

竟发现几乎没有用 STL deque 的。

故写了个青春版题解。

 AC 代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 5e5+10;
int f[N],a[N];
int d,k;
int n;
int x[N];
deque<int> q;
int ct(int mid){
	int l = max(1LL,d-mid),r = d+mid;//
	//l <= xi-xj <= r
	int j = 0;
	q.clear();
	memset(f,-0x3f,sizeof(f));
	int ans = 0;
	f[0] = 0;
	for(int i = 1;i <= n;i++){
		while(j < i&&l <= x[i]-x[j]){
		//	cout<<j<<" "<<i<<endl;
			while(!q.empty()&&f[q.back()] < f[j])q.pop_back();
			q.push_back(j);
			j++;
		}
		while(!q.empty()&& x[i]-x[q.front()] > r){
		//	cout<<"out "<<q.front()<<endl;
			q.pop_front();
		}
		if(!q.empty())f[i] = f[q.front()]+a[i];
	//	cout<<i<<" ans "<<f[i]<<endl;
		ans = max(ans,f[i]);
	}
	return ans;
} 
int find(int l,int r){
	while(l <= r){
		int mid = (l+r)/2;
		//cout<<mid<<" "<<ct(mid)<<" "<<(ct(mid) >= k)<<endl;
		if(ct(mid) >= k)r = mid-1;
		else l = mid+1;
	}
	return l;
}
signed main(){
	cin>>n>>d>>k;
	for(int i = 1;i <= n;i++){
		cin>>x[i]>>a[i];
	}
	if(find(0,1e9+7) > 1e9){
		cout<<-1;
		return 0;
	}
	cout<<find(0,x[n]+1); 
	return 0;
}

 

 

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值