1 条题解

  • 1
    @ 2025-5-6 18:41:40

    懒得介绍!!!!!! 代码:

    using namespace std;
    /*
    题目大意:在有 n 个点的情况下,补充 k 个点
    选出最多的点,满足:
    (1) 点是相邻的
    (2) 坐标单调不减
    */
    const int N = 510,K = 110;
    struct node{
    	int x,y;
    }a[N];
    //f[i][j]:以第 i 个点结尾,补充 j 个点,形成最长上升点列的长度
    int f[N][K];
    int n,k;
    //按 x 升序, x 相等按 y 升序
    bool cmp(node n1,node n2){
    	return n1.x<n2.x || (n1.x==n2.x && n1.y<n2.y);
    }
    int main(){
    	freopen("point.in", "r", stdin);
    	freopen("point.out","w",stdout);
    	cin>>n>>k;
    	for(int i = 1;i <= n;i++){
    		cin>>a[i].x>>a[i].y;
    	}
    	//排序
    	sort(a+1,a+n+1,cmp);
    	//边界条件
    	for(int i = 1;i <= n;i++){
    		for(int j = 0;j <= k;j++){
    			f[i][j] = j + 1;
    		}
    	}
    	//从第 2 个点开始递推
    	int c;
    	for(int i = 2;i <= n;i++){
    		//枚举每个点前面的点
    		for(int t = 1;t < i;t++){
    			//只能取第 i 个点左下角的点
    			if(a[t].y > a[i].y) continue;
    			//c:从第 t 个点到第 i 个点要补充点的数量
    			c = a[i].x-a[t].x + a[i].y-a[t].y - 1;
    			//枚举 j 的值:补充点的数量
    			for(int j = c;j <= k;j++){
    				f[i][j] = max(f[i][j],f[t][j-c]+c+1);
    			}
    		}
    	}
    	//求答案:求以哪个点结尾形成的上升点列的长度是最长的
    	int ans = 0;
    	for(int i = 1;i <= n;i++) ans = max(ans,f[i][k]);
    	cout<<ans;
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

    信息

    ID
    305
    时间
    1000ms
    内存
    256MiB
    难度
    9
    标签
    递交数
    12
    已通过
    5
    上传者