CSP-J 2022 T4 上升点列
[CSP-J 2022] 上升点列
题目描述
在一个二维平面内,给定
你在自由添加
输入格式
第一行两个正整数
接下来
输出格式
输出一个整数表示满足要求的序列的最大长度。
样例 #1
样例输入 #1
8 2
3 1
3 2
3 3
3 6
1 2
2 2
5 5
5 3
样例输出 #1
8
样例 #2
样例输入 #2
4 100
10 10
15 25
20 20
30 30
样例输出 #2
103
提示
【样例 #3】
见附件中的 point/point3.in 与 point/point3.ans。
第三个样例满足
【样例 #4】
见附件中的 point/point4.in 与 point/point4.ans。
【数据范围】
保证对于所有数据满足:
| 测试点编号 | |||
|---|---|---|---|
思路:
开始看到这道题以后,就感觉和LIS有点相似,然后关注了一下数据规模,发现数据规模比较小,开始操作。
题目大意:在已知
还是先把代码放过来了,突然开会暂停~:
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
struct node{
int x,y;
} a[505];
int dp[505][105]; //dp[i][j] 表示在以第i个点为结尾,添加j个点的序列的最大长度
int dis(node a,node b){
return abs(a.x-b.x)+abs(a.y-b.y);
}
bool cmp(node a, node b){
if(a.x!=b.x){
return a.x<b.x;
}
else if(a.y!=b.y){
return a.y<b.y;
}
}
int main(){
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i].x>>a[i].y;
}
sort(a+1,a+n+1,cmp); //通过排序 需要保证单调递增
int ans=0;
/*
现在有两个点i p 他们之间的距离如果是 j的话,需要添加 j-1个点
*/
for(int i=1;i<=n;i++){ //枚举n个点 计算dp[i][k]的最大值
for(int j=0;j<=k;j++){ //能够添加j个点
dp[i][j]=j+1; //最短也得是添加的j个点连接后形成的长度为j+1的序列
for(int p=1;p<i;p++){ //枚举前面的点 p
//验证一下枚举到的p点
if(a[p].x<=a[i].x && a[p].y<=a[i].y){
int d=dis(a[i],a[p])-1; //需要的点的个数 距离需要+1
if(d<=j) //需要添加的点的个数没有超过提供的点的个数
dp[i][j]=max(dp[i][j],dp[p][j-d]+d+1);
}
}
}
}
for(int i=1;i<=n;i++){
ans=max(ans,dp[i][k]);
}
cout<<ans;
return 0;
}