CodeForces - 1409E Two Platforms(瞎搞)

题面:

在这里插入图片描述在这里插入图片描述

题意:

在一个二维平面上,有许多点,其坐标为 ( x i , y i ) (x_i,y_i) (xi,yi) ,它们会沿 y y y 轴的负方向运动,你有两块长度为 k k k 且平行于 x x x 轴的的板子去save它们,问最多能save多少个点。(大概就是这么个意思)

思路:

有个憨憨想法:
d p [ i ] [ 1 ] dp[i][1] dp[i][1] 表示第一块板子右端与直线x=i对齐,能save的点的个数
d p [ i ] [ 2 ] dp[i][2] dp[i][2] 表示第二块板子右端与直线x=i对齐,能save的点的个数
d p [ i ] [ 2 ] = m a x j < = i − k d p [ j ] [ 1 ] + d p [ i ] [ 1 ] dp[i][2] = max_{j <= i - k}dp[j][1] + dp[i][1] dp[i][2]=maxj<=ikdp[j][1]+dp[i][1]
二分 + 离散化 + 递推???瞎搞过的

#include<bits/stdc++.h>
#define ll long long
#define ms(x,a) memset(x,a,sizeof(x))
#define inf 0x3f3f3f3f
#define db double
using namespace std;

const int maxn = 2e5 + 10;
int x[maxn],mx[maxn],dp[maxn][3],tnt[maxn];
map<int,int>mp;

int main() {
	int t;
	scanf("%d",&t);
	for(int ca = 1;ca <= t; ++ca){
		int n,k;
		scanf("%d%d",&n,&k);
		mp.clear();
		for(int i = 1;i <= n; ++i){
			scanf("%d",&x[i]);
			mp[x[i]]++;
			dp[i][1] = dp[i][2] = mx[i] = 0;
		}
		for(int i = 1;i <= n; ++i){
			int y;
			scanf("%d",&y);
		}
		map<int,int>::iterator it;
		n = 0;
		for(it = mp.begin();it != mp.end(); ++it){
			x[++n] = it->first;
		}
		tnt[0] = 0;
		for(int i = 1;i <= n; ++i){
			tnt[i] = tnt[i - 1] + mp[x[i]];
			int pos = lower_bound(x + 1,x + 1 + i,x[i] - k) - x;
			dp[i][1] = tnt[i] - tnt[pos - 1];
			mx[i] = max(mx[i - 1],dp[i][1]);
		}
		int ans = 0;
		for(int i = 1;i <= n; ++i){
			int pos = lower_bound(x + 1,x + 1 + i,x[i] - k) - x;
			dp[i][2] = mx[pos - 1] + dp[i][1];
			ans = max(ans,dp[i][2]);
		}
		cout<<ans<<endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值