10 条题解

  • -1
    @ 2023-3-8 21:07:30

    首先我们定义好结构体,把输入的点以x为第一关键字,y为第二关键字进行排序

    struct node{
    	int x,y;
    	bool operator< (const node &w) const
    	{
    		if(x==w.x)	return y<w.y;
    		return x<w.x;
    	}
    }a[501];
    

    设f[i][j]为枚举到第i个点,还有j个自由点时序列最大长度,则状态转移方程为

    f[i][j]=max(f[i][j],f[t][j+d+1]

    t是从1到i-1,d是第i个点和第t个点之间要添加的自由点个数 求完所有序列的长度后,再找出最大长度就做完了

    代码

    #include<algorithm>
    #include<iostream>
    #include<cmath>
    using namespace std;
    int n,k;
    struct node{
    	int x,y;
    	bool operator< (const node &w) const
    	{
    		if(x==w.x)	return y<w.y;
    		return x<w.x;
    	}
    }a[501];
    int f[501][101];
    int main(){
        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++){
            f[i][k]=1;//初始没用自由点的值为1
            for(int j=0;j<=k;j++){
                for(int t=1;t<i;t++){
                    if(a[t].x>a[i].x||a[t].y>a[i].y)	continue;//不符合题意跳过
                    int x=abs(a[i].x-a[t].x);
                    int y=abs(a[i].y-a[t].y);
                    int d=x+y-1;//要加多少个自由点
                    if(j+d>k){//自由点不够
                        continue;
                    }
                    f[i][j]=max(f[i][j],f[t][j+d]+d+1);
                }
            }
        }
        int ans = 0;
        for(int i=1;i<=n;i++){
            for(int j=0;j<=k;j++){
                ans=max(ans,j+f[i][j]);
            }
        }
        cout<<ans;
        return 0;
    }
    

    信息

    ID
    2919
    时间
    1000ms
    内存
    256MiB
    难度
    8
    标签
    递交数
    111
    已通过
    36
    上传者