- 上升点列
题目ID:9698拓展题文件操作100分
最新提交:
Runtime Error
0 分
历史最高:
Runtime Error
0 分
时间限制: 1000ms
空间限制: 262144kB
输入文件名: rise.in
输出文件名: rise.out
题目描述
在一个二维平面内,给定 n 个整数点 (xi, yi),此外你还可以自由添加 k 个整数点。你在自由添加 k 个点后,还需要从 n + k 个点中选出若干个整数点并组成一个序列,使得序列中任意相邻两点间的欧几里得距离恰好为 1 而且横坐标、纵坐标值均单调不减,即 xi+1 - xi = 1, yi+1 = yi 或 yi+1 - yi = 1, xi+1 = xi。请给出满足条件的序列的最大长度。
输入格式
第一行两个正整数 n, k 分别表示给定的整点个数、可自由添加的整点个数。接下来 n 行,第 i 行两个正整数 xi, yi 表示给定的第 i 个点的横纵坐标。
输出格式
输出一个整数表示满足要求的序列的最大长度。
样例
Input 1
8 2 3 1 3 2 3 3 3 6 1 2 2 2 5 5 5 3
Output 1
8
Input 2
4 100 10 10 15 25 20 20 30 30
Output 2
103
样例解释
样例1的输入中,给定了8个整数点和2个可自由添加的整数点。满足条件的序列为[(1, 2), (2, 2), (3, 1), (3, 2), (3, 3), (3, 6), (5, 5), (5, 3)],共有8个点。样例2中给定了4个整数点和100个可自由添加的整数点。满足条件的序列可以选择任意四个点,然后再依次添加100个自由点,共有103个点。
数据范围
【数据范围】保证对于所有数据满足:1 ≤ n ≤ 500,0 ≤ k ≤ 100。对于所有给定的整点,其横纵坐标 1 ≤ xi, yi ≤ 10^9,且保证所有给定的点互不重合。对于自由添加的整点,其横纵坐标不受限制。
我代码
#include <bits/stdc++.h>
using namespace std;
const int N = 510;
const int K = 110;
struct node {
int x, y;
};
node p[N];
int n, k;
int f[N][K];
bool cmp(node a, node b) {
if (a.x != b.x) return a.x < b.x;
return a.y < b.y;
}
int main() {
cin >> n >> k;
for (int i = 1; i <= n; i++) {
cin >> p[i].x >> p[i].y;
}
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= k; j++) {
f[i][j] = 1;
}
}
sort(p + 1, p + n + 1, cmp);
for (int i = 2; i <= n; i++) {
for (int j = 1; j < i; j++) {
if (p[i].y < p[j].y) {
continue;
}
int w = p[i].x - p[j].x + p[i].y - p[j].y - 1;
for (int u = w; u <= k; u++) {
f[i][u] = max(f[i][u], f[j][u - w] + 1);
}
}
}
int sum = 0;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= k; j++) {
sum = max(sum, f[i][k]);
}
}
cout << sum + k;
return 0;
}
