首页 > 其他分享 >【动态规划、dp】[CSP-J 2022] 上升点列 题解

【动态规划、dp】[CSP-J 2022] 上升点列 题解

时间:2024-08-18 12:23:56浏览次数:15  
标签:yi int 题解 leq edge 点列 2022 dp dis

题目描述

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

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

【数据范围】

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

思路

考虑动态规划,记 d p i , j dp_{i,j} dpi,j​ 表示以第 i i i 个点为结尾,已经插入 j j j 个自由点的最长长度。

首先将点对按照 x , y x,y x,y 大小排个序,确保转移时横纵坐标比当前节点小的点对都在它前面,否则无法转移。

容易发现, d p i , j = max ⁡ l = 1 i − 1 d p l , j − d i s ( i , l ) + 1 + d i s ( i , l ) + 1 , ( y i ≥ y l , j − d i s ( i , l ) + 1 ≥ 0 ) dp_{i,j} = \max_{l=1}^{i - 1}{dp_{l,j -dis(i,l)+1} + dis(i,l)+1},(y_i \geq y_l,j -dis(i,l)+1 \geq 0) dpi,j​=maxl=1i−1​dpl,j−dis(i,l)+1​+dis(i,l)+1,(yi​≥yl​,j−dis(i,l)+1≥0), d p i , j dp_{i,j} dpi,j​ 初始值赋值为 j + 1 j+1 j+1(全部用在它前面)。

解释:因为两个点中间因插入的点对数量等于它们欧几里得距离减去一(因为头尾都已经有了),文中 d i s ( i , l ) dis(i,l) dis(i,l) 表示的就是两者的欧几里得距离剪去 1 1 1。计算方式如下:

int dis(int a,int b) {
	return abs(edge[a].x - edge[b].x) + abs(edge[a].y - edge[b].y) - 1;
}

最后输出的答案就是 a n s ans ans 就是 d p i , j + ( k − j ) dp_{i,j} + (k - j) dpi,j​+(k−j) 的最大值(加上 k − j k-j k−j 代表剩下所有没用完的直接加在该点后面)
在这里插入图片描述

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,k;
struct node{
	int x,y;
	friend bool operator <(node a,node b) {
		if(a.x == b.x) return a.y < b.y;
		return a.x < b.x; 
	}
}edge[505];
int dp[505][105],ans = -1e18;
int dis(int a,int b) {
	return abs(edge[a].x - edge[b].x) + abs(edge[a].y - edge[b].y) - 1;
}
signed main() {
	scanf("%lld %lld",&n,&k);
	for(int i = 1;i <= n;i++) scanf("%lld%lld",&edge[i].x,&edge[i].y);
	sort(edge + 1,edge + n + 1);
	for(int i = 1;i <= n;i++) {
		for(int j = 0;j <= k;j++) {
			dp[i][j] = j + 1;
			for(int l = 1;l < i;l++) {
				int d = dis(i,l);
				if(edge[l].y <= edge[i].y and d <= j) {
					dp[i][j] = max(dp[i][j],dp[l][j - d] + d + 1);
				}
			}
			ans = max(ans,dp[i][j] + k - j);
		}
	}
	printf("%lld\n",ans);
    return 0;
}

标签:yi,int,题解,leq,edge,点列,2022,dp,dis
From: https://blog.csdn.net/guozhetao/article/details/141297824

相关文章

  • 题解:AT_abc367_e [ABC367E] Permute K times
    题意给你一个长度为\(N\)的序列\(X\),其中每个元素都介于\(1\)和\(N\)之间(含),以及一个长度为\(N\)的序列\(A\)。打印在\(A\)上执行以下操作\(K\)次的结果。将\(A_i\)替换为\(A_{X_i}\)。每个操作同时进行。思路元素\(i\)经过\(k\)次变化后的值就是元素......
  • 对树链剖分的爱 题解
    前言题目链接:洛谷。题意简述给出一棵\(n\)个节点以\(1\)为根的有根树。对于第\(2\leqi\leqn\)个节点,其父亲\(f_i\)在\([l_i,r_i]\)中均匀随机。每个树的边有边权,初始为\(0\)。现在有\(m\)次操作,第\(i\)次操作表示将\((u_i,v_i)\)的路径上所有的边的权值统......
  • Huawei Matebook e 2022 安装 archlinux 双系统
    本文同步发布于我的网站安装之前wifi名称修改为英文+数字的,以防之后没法联网准备好U盘并使用GPT分区表写入最新的arch镜像。基础安装开机按F2进入UEFI/BIOS设置,将SecureBoot(安全启动)关闭,按F10保存重启。开机按F12进入启动菜单,选择U盘启动。先按e在引......
  • AtCoder Beginner Contest 367 题解(E~G)
    E转换关系看作有向边,\(n\)点\(n\)边构成基环树森林,基环树森林k后继唯一,记f[i][j]为点\(i\)的\(2^j\)级祖先,随便倍增。F一眼哈希,不知道有没有不哈希的做法。在这里我们不关心元素的顺序,只关心元素是否出现以及出现几次,考虑一个\(n\)位\(n+1\)进制数,\(a_i\)出现一......
  • [题解]CF76B Mice
    思路比较简单的贪心。对于可以选择两个奶酪的老鼠,我们先将它们忽略掉。现在所有老鼠所吃的奶酪是唯一确定的。考虑加上可以选择两个奶酪的老鼠如何选择。显然,如果它可以选择一个没有任何老鼠吃过的奶酪,它必然这样选择。其次,如果它可以选择的奶酪被吃掉的时间\(t\)与它到达奶......
  • ABC 367 题解
    AtCoderBeginnerContest367题解:\(Problem\hspace{2mm}A-Shout\hspace{2mm}Everyday\)题目链接opinion:~~code:#include<bits/stdc++.h>#definelllonglong#definepiipair<int,int>usingnamespacestd;lla,b,c;intmain(){ i......
  • abc364 题解
    第一次场切A~F,写个题解纪念一下。比赛链接:https://atcoder.jp/contests/abc367A-ShoutEveryday题意:高桥每天\(B\)时刻睡觉,\(C\)时刻起床(\(B,C\)时刻也在睡觉),请问高桥\(A\)时刻是否没睡。思路:对于\(B<=C\)和\(B>C\)分别处理即可。代码:https://atcoder.jp/con......
  • 题解:AtCoder Beginner Contest 367
    总体情况A题意在AtCoder王国,居民们每天都要在\(A\)点大声喊出他们对章鱼烧的热爱。住在AtCoder王国的高桥每天\(B\)点睡觉,\(C\)点起床(\(24\)小时钟)。他醒着的时候可以喊出对章鱼烧的爱,但睡着的时候却不能。判断他是否每天都能喊出对章鱼烧的爱。这里,一天有\(24......
  • P10886 【MX-S3-T2】「FeOI Round 1」Journey 题解
    我们肯定是要先求出来一个位置被加的次数,然后和权值乘一下就行。对于一个位置\(i\),右端点\(b\)肯定是随便选,一共\(n-i+1\)种情况。再是对于每一种步长\(c\),左端点\(a\)都有\(\left\lceil\dfrac{i}{c}\right\rceil\)种取值,暴力计算,时间复杂度\(O(n^2)\)。(提交记录)考虑......
  • P10888 【MX-S3-T4】「FeOI Round 1」醒餞の鳥 (feat. Feryquitous) 题解
    话说这题真的有紫吗(问号注意到数据范围中提到$\sum{nm}\le2\times10^5$,这里实际上是隐含了\(\min(n,m)\le\sqrt{2\times10^5}\)的。我们考虑根据\(n\)和\(m\)的大小关系设计出不同的算法。\(m<n\)一个比较直接的想法是对于每一个科目先按该科目的分数排序,这样......