P8816 [CSP-J 2022] 上升点列(民间数据)

题目描述

在一个二维平面内,给定 nn 个整数点 (x_i, y_i)(xi​,yi​),此外你还可以自由添加 kk 个整数点。

你在自由添加 kk 个点后,还需要从 n + kn+k 个点中选出若干个整数点并组成一个序列,使得序列中任意相邻两点间的欧几里得距离恰好为 11 而且横坐标、纵坐标值均单调不减,即 x_{i+1} - x_i = 1, y_{i+1} = y_ixi+1​−xi​=1,yi+1​=yi​ 或 y_{i+1} - y_i = 1, x_{i+1} = x_iyi+1​−yi​=1,xi+1​=xi​。请给出满足条件的序列的最大长度。

输入格式

第一行两个正整数 n, kn,k 分别表示给定的整点个数、可自由添加的整点个数。

接下来 nn 行,第 ii 行两个正整数 x_i, y_ixi​,yi​ 表示给定的第 ii 个点的横纵坐标。

输出格式

输出一个整数表示满足要求的序列的最大长度。

输入输出样例

输入 #1复制

8 2
3 1
3 2
3 3
3 6
1 2
2 2
5 5
5 3

输出 #1复制

8

输入 #2复制

4 100
10 10
15 25
20 20
30 30

输出 #2复制

103

说明/提示

【样例 #3】

见附件中的 point/point3.in 与 point/point3.ans

第三个样例满足 k = 0k=0。

【样例 #4】

见附件中的 point/point4.in 与 point/point4.ans

【数据范围】

保证对于所有数据满足:1 \leq n \leq 5001≤n≤500,0 \leq k \leq 1000≤k≤100。对于所有给定的整点,其横纵坐标 1 \leq x_i, y_i \leq {10}^91≤xi​,yi​≤109,且保证所有给定的点互不重合。对于自由添加的整点,其横纵坐标不受限制。

测试点编号 n \leqn≤ k \leqk≤ x_i,y_i \leqxi​,yi​≤
1 \sim 21∼2 1010 00 1010
3 \sim 43∼4 1010 100100 100100
5 \sim 75∼7 500500 00 100100
8 \sim 108∼10 500500 00 {10}^9109
11 \sim 1511∼15 500500 100100 100100
16 \sim 2016∼20 500500 100100 {10}^9109

附件下载

point.zip1.53KB

#include
using namespace std;
int n,k,f[510][510],ans;
struct node {
	int x,y;
} a[510];
bool cmp(node a,node b) {    //排序
	if(a.x!=b.x) {
		return a.x>n>>k;
	int x,y;
	for(int i=1; i<=n; i++) {
		cin>>a[i].x>>a[i].y;
	}
	sort(a+1,a+1+n,cmp);
	for(int i=1; i<=n; i++) {
		for(int j=0; j<=k; j++) {
			f[i][j]=j+1;
			for(int t=1; ta[i].y) {    //判断是否符合要求
					continue;
				}
				int cnt=a[i].x-a[t].x+a[i].y-a[t].y-1;    //位置差-1
				if(j>=cnt) {                              //如果可以执行
					f[i][j]=max(f[i][j], f[t][j-cnt]+cnt+1);    //改变数值
				}
			}
		}
	}
	for(int i=1; i<=n; i++) {
		ans=max(ans,f[i][k]);    //比较
	}
	cout<

你可能感兴趣的:(NOIP普及组,洛谷,算法)