4139: 上升点列 [CSP-J 2022]
内存限制:128 MB
时间限制:1.000 S
评测方式:文本比较
命题人:
提交:1
解决:1
题目描述
在一个二维平面内,给定 个整数点 ,此外你还可以自由添加 个整数点。
你在自由添加 个点后,还需要从 个点中选出若干个整数点并组成一个序列,使得序列中任意相邻两点间的欧几里得距离恰好为 而且横坐标、纵坐标值均单调不减,即 , 或 。请给出满足条件的序列的最大长度。
输入
第一行两个正整数 分别表示给定的整点个数、可自由添加的整点个数。
接下来 行,第 行两个正整数 表示给定的第 个点的横纵坐标。
输出
输出一个整数表示满足要求的序列的最大长度。
样例输入 复制
8 2
3 1
3 2
3 3
3 6
1 2
2 2
5 5
5 3
样例输出 复制
8
提示
【数据范围】
保证对于所有数据满足:,。对于所有给定的整点,其横纵坐标 ,且保证所有给定的点互不重合。对于自由添加的整点,其横纵坐标不受限制。
#include<bits/stdc++.h>
using namespace std;
const int maxn=500+10;
const int maxk=100+10;
int n, k;
pair<int,int> a[maxn];
int f[maxn][maxk];
/*
f[i][j]表示以第i个点为结尾(即右上角)且允许添加j个点时的最长答案。
转移时,枚举点i之前添加哪个节点,遍历所有其他点即可。
时间复杂度O(n*n*k)
*/
int main(){
//freopen("point.in","r",stdin);
//freopen("point.out","w",stdout);
scanf("%d%d",&n,&k);
for (int i=1;i<=n; i++) scanf("%d%d",&a[i].first, &a[i].second);
sort(a+1,a+n+1);
for(int i=1; i<=n; i++)
for(int j=0;j<=k; j++){
f[i][j]=j+1;
for(int p=1; p<i; p++)
if(a[p].first<=a[i].first && a[p].second<=a[i].second){
int d=a[i].first -a[p].first + a[i].second - a[p].second - 1;
if(d<=j) f[i][j]= max(f[i][j],f[p][j-d]+d+1);
}
}
int ans =0;
for(int i=1;i<=n; i++) ans = max(ans, f[i][k]);
printf("%d\n", ans);
return 0;
}