1409E. Two Platforms(枚举,二分)

E. Two Platforms

这题还是有一些细节的…

题意:

有两块长k的板子,可以在任意整数座标水平放置,问最多有多少小球的投影在板子上

首先注意到所有小球只关系它的 x x x座标,与 y y y座标无关

因为同样的 x x x座标,板子的 y y y座标肯定无穷小(能接住所有掉下来的小球)

所以现在问题是两段长k的线段,最多能覆盖多少点?

所 以 现 在 问 题 就 不 难 了 所以现在问题就不难了

先 对 小 球 x 座 标 排 个 序 先对小球x座标排个序 x

然 后 枚 举 第 一 块 木 板 从 第 i 个 小 球 开 始 覆 盖 然后枚举第一块木板从第i个小球开始覆盖 i

用 二 分 查 找 出 最 多 能 覆 盖 到 第 j 个 小 球 用二分查找出最多能覆盖到第j个小球 j

那 么 第 二 块 木 板 是 从 j + 1 个 小 球 开 始 覆 盖 最 优 吗 ? ? 那么第二块木板是从j+1个小球开始覆盖最优吗?? j+1??

当 然 不 是 , 可 以 从 j + 2 开 始 覆 盖 , 可 以 从 j + 3 开 始 覆 盖 . . . . 当然不是,可以从j+2开始覆盖,可以从j+3开始覆盖.... ,j+2,j+3....

所 以 预 处 理 一 个 h o u [ i ] 数 组 , 表 示 从 第 [ i , n ] 个 小 球 开 始 覆 盖 的 最 优 取 值 所以预处理一个hou[i]数组,表示从第[i,n]个小球开始覆盖的最优取值 hou[i],[i,n]

这 样 就 可 以 枚 举 第 一 块 板 子 快 速 得 到 第 二 块 板 子 的 最 优 秀 值 , 细 节 看 代 码 吧 这样就可以枚举第一块板子快速得到第二块板子的最优秀值,细节看代码吧 ,

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=2e5+10;
int a[maxn],b[maxn],c[maxn],pre[maxn];
bool com( int a,int b){
	return a<b;
}
int qian[maxn],hou[maxn];
signed main()
{
	int t,n,k;
	cin >> t;
	while( t-- )
	{
		cin >> n >> k;
		for(int i=1;i<=n;i++)	cin >> a[i];
		for(int i=1;i<=n;i++)	cin >> b[i];
		sort(a+1,a+1+n,com);
		for(int i=n;i>=1;i--)
		{
			int nowx=a[i]+k;//从第i个小球开始覆盖,最远可以覆盖到nowx
			int index=upper_bound(a+1,a+1+n,nowx)-a;//刚好大于nowx的索引 
			hou[i]=max( hou[i+1],index-i );//取max,因为数组hou[i]的含义是从[i,n]任选一个小球开始覆盖的最优值 
		}
		int ans=0;
		for(int i=1;i<=n;i++)//枚举第一块木板从i位置开始覆盖 
		{
			int nowx=a[i]+k;
			int index=upper_bound(a+1,a+1+n,nowx)-a;//刚好大于nowx的索引 
			ans=max( ans,hou[index]+(index-i) );
		}
		cout << ans << endl;
		for(int i=0;i<=n+1;i++)	hou[i]=0;
	}
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值