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; }