#CSPJ202203. 上升点列(AC代码)

2022年 CSP_J 第二轮 第三题

#CSPJ202203. [CSP-J 2022] 上升点列

题目描述

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

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

输入格式

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

接下来 n 行,第 i 行两个正整数 x_i, y_i 表示给定的第 i 个点的横纵坐标。

输出格式

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

样例 #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

第三个样例满足 k=0

【样例 #4】

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

【数据范围】

保证对于所有数据满足:1 \leq n \leq 5000 \leq k \leq 100。对于所有给定的整点,其横纵坐标 1 \leq x_i, y_i \leq {10}^9,且保证所有给定的点互不重合。对于自由添加的整点,其横纵坐标不受限制。

测试点编号n≤k≤x_i,y_i \leq
1∼210010
3∼4100100
5∼75000
8∼10{10}^9
11∼15100100
16∼20{10}^9

【题解】

暂无

【代码】

 

#include <bits/stdc++.h>
using namespace std;
int dp[501][101];
int dis[501][501];
struct node//结构体 
{
    int x, y;
}a[501];
bool operator<(node a,node b)//排序 
{
	if(a.x!=b.x)return a.x<b.x;
	return a.y<b.y;
}
int judge(int i,int j)//判断 
{
    if(i==j)return 101;
    if(a[i].x>a[j].x)return 101;
    if(a[i].y>a[j].y)return 101;
    return a[j].x-a[i].x+a[j].y-a[i].y-1;
}
int main()
{
    //freopen("point.in","r",stdin);
    //freopen("point.out","w",stdout);
    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);
    for(int i=1;i<=n;i++){ 
        for(int j=1;j<=n;j++){
            dis[i][j]=judge(i,j);
        }
    }
    int ans=0; 
    for(int i=1;i<=n;i++){
        dp[i][0]=1;
        for(int v=0;v<=k;v++){
            if(v)dp[i][v]=dp[i][v-1]+1;
            for (int j=1;j<i;j++){
                int c=dis[j][i];
                if(c>v)continue;
                dp[i][v]=max(dp[i][v],dp[j][v-c]+c+1);
            }
        }
        ans=max(ans,dp[i][k]);
    }
    cout<<ans<<endl;
}

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值