当前位置: 首页 > article >正文

信息学奥赛一本通 2089:【22CSPJ普及组】上升点列(point) | 洛谷 P8816 [CSP-J 2022] 上升点列

【题目链接】

ybt 2089:【22CSPJ普及组】上升点列(point)
洛谷 P8816 [CSP-J 2022] 上升点列

【题目考点】

1. 动态规划
2. 曼哈顿距离

平面直角坐标系中两个整数点之间的绝对轴距总和。
p 1 ( x 1 , y 1 ) p_1(x_1,y_1) p1(x1,y1)和点 p 2 ( x 2 , y 2 ) p_2(x_2,y_2) p2(x2,y2)的曼哈顿距离为
d i s ( p 1 , p 2 ) = ∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ dis(p_1,p_2) = |x_1-x_2|+|y_1-y_2| dis(p1,p2)=x1x2+y1y2

【解题思路】

给定n个点,添加k个点,看能形成上升点序列的最大长度。
上升点序列:相邻两点间的曼哈顿距离为1,且横纵坐标值单调不减的点序列。
点的数量可以变化,添加的点的数量可以变化,因此考虑将这两个量设为阶段。

状态定义
  • 阶段:已有前i个点,添加j个点
  • 决策:将可以添加的点添加到哪个位置
  • 策略:添加点后得到点序列的方案
  • 策略集合:
    直接考虑,应该是已有前i个点,再添加j个点得到的所有上升点序列。
    考虑到应该让每个已有点参与到构成点序列的过程中,这样才能考虑到所有可能的上升点序列方案。因此这里再加一层限定,就是第i点必须参与到上升点序列中。
    因此策略集合为:已有前i个点,再添加j个点构成的包含第i点的所有上升点序列。
  • 条件:上升点序列长度最大
  • 统计量:序列长度

状态定义: d p [ i ] [ j ] dp[i][j] dp[i][j]:已有的前i个点中添加j个点所构成的所有包含第i点的上升点序列的最大长度。
初始状态:第i点在添加j个点后,至少能得到一个长度为j+1的上升点序列。因此有初始状态 d p [ i ] [ j ] = j + 1 dp[i][j] = j+1 dp[i][j]=j+1

状态转移方程
  • 策略集合:已有前i个点,再添加j个点构成的包含第i点的所有上升点序列
  • 分割策略集合:根据上升点序列中第i点的前一个已有点分割策略集合。

设第 i i i点前的第一个已有点为第 h h h点, h h h最小可以选择第1号点,最大时可以是第 i − 1 i-1 i1点,因此 1 ≤ h < i 1\le h < i 1h<i
那么在上升点序列中从第 h h h点到第 i i i点之间就没有已有点了,全部都是新添加的点。生成的点序列中第 h h h点到第 i i i点的情况为:
h h h点,添加点1,添加点2,…,添加点x,第 i i i点。

已有点中是第i点的坐标为 ( x i , y i ) (x_i, y_i) (xi,yi)
如果要在第h点和第i点两点之间添加点使其形成一个上升点序列,需要添加的点的数量为第h点和第i点两点之间的曼哈顿距离减1,即 d i s ( h , i ) − 1 = ∣ x h − x i ∣ + ∣ y h − y i ∣ − 1 dis(h,i)-1=|x_h-x_i|+|y_h-y_i|-1 dis(h,i)1=xhxi+yhyi1(其中 d i s ( h , i ) dis(h,i) dis(h,i)是第h点和第i点两点之间的曼哈顿距离)

能将第h点和第i点连起来形成一个上升点序列至少需要 d i s ( h , i ) − 1 dis(h,i)-1 dis(h,i)1个点,现在有 j j j个可添加点,因此必须满足 j ≥ d i s ( h , i ) − 1 j\ge dis(h,i)-1 jdis(h,i)1,才可以形成一个上升点序列。
同时,由于上升点序列要求横纵坐标单调不减,第h点 ( x h , y h ) (x_h, y_h) (xh,yh)在第i点 ( x i , y i ) (x_i,y_i) (xi,yi)点前,一定要满足 x h ≤ x i x_h\le x_i xhxi y h ≤ y i y_h\le y_i yhyi
可以预先将所有已有点按照x从小到大、x相等时y从小到大进行排序。这样排序后可以保证上升点序列中第i点的下一个点,一定在排序后的已有点序列第i点的后面。(因为从第i点到第i点前面的点,一定是横坐标减少或纵坐标减少)。
如果满足以上条件,则可以选择第h点作为第i点前的第一个已有点,两点之间添加 d i s ( h , i ) − 1 dis(h, i)-1 dis(h,i)1个新的点,形成上升点序列。

已有的前 i i i个点中添加 j j j个点所构成的所有包含第 i i i点的上升点序列的最大长度 d p [ i ] [ j ] dp[i][j] dp[i][j],是已有前h个点,添加 j − ( d i s ( h , i ) − 1 ) j-(dis(h, i)-1) j(dis(h,i)1)个点构成的包含第 h h h点的最长的上升点序列的长度,加上从第h点到第i点不包含第h点的点的数量,也就是第h点到第i点的曼哈顿距离 d i s ( h , i ) dis(h, i) dis(h,i)
接下来对于 1 ≤ h < i 1\le h< i 1h<i的所有情况,求 d p [ i ] [ j ] dp[i][j] dp[i][j]的最大值。

状态转移方程: d p [ i ] [ j ] = m a x { d p [ h ] [ j − d i s ( h , i ) + 1 ] + d i s ( h , i ) } , 1 ≤ h < i dp[i][j] = max\{dp[h][j-dis(h,i)+1]+dis(h,i)\}, 1\le h < i dp[i][j]=max{dp[h][jdis(h,i)+1]+dis(h,i)},1h<i

最终得到的最长的上升点序列可能以任何一个已有点为结尾,因此结果为 d p [ 1 ] [ k ] ∼ d p [ n ] [ k ] dp[1][k]\sim dp[n][k] dp[1][k]dp[n][k]中的最大值

【题解代码】

解法1:动态规划

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define N 505
#define K 105
using namespace std;
struct Point
{
	int x, y;
} p[N];
bool cmp(Point a, Point b)
{
	return a.x < b.x || a.x == b.x && a.y < b.y;
}
int dis(int i, int j)//p[i]到p[j]的曼哈顿距离 
{
	return abs(p[i].x-p[j].x)+abs(p[i].y-p[j].y);
}
int dp[N][K], ans;//已有的前i个点中添加j个点所构成的所有包含第i点的上升点序列的最大长度。
int main()
{
	int n, k;
	cin >> n >> k;
	for(int i = 1; i <= n; ++i)
		cin >> p[i].x >> p[i].y;
	sort(p+1, p+n+1, cmp);
	for(int i = 1; i <= n; ++i)
	{
		for(int j = 0; j <= k; ++j)
		{
			dp[i][j] = j+1;
			for(int h = 1; h < i; ++h) 
				if(j >= dis(h, i)-1 && p[h].x <= p[i].x && p[h].y <= p[i].y) 
					dp[i][j] = max(dp[i][j], dp[h][j-dis(h, i)+1]+dis(h, i));
		}
		ans = max(ans, dp[i][k]);
	}
	cout << ans;
	return 0;
}

http://www.kler.cn/a/533678.html

相关文章:

  • PostgreSQL技术内幕24:定时任务调度插件pg_cron
  • 深入理解Node.js_架构与最佳实践
  • 8.原型模式(Prototype)
  • 计算机基础知识(第二篇)
  • 4 前端前置技术(中):node.js环境
  • go-zero学习笔记(三)
  • 题解:洛谷 P1608 路径统计
  • 2.5寒假作业
  • springboot校园数字化图书馆系统设计与实现
  • 数据结构【链式队列】
  • DeepSeek本地部署及其他应用接入
  • 【TensorFlow】T1:实现mnist手写数字识别
  • 基于springboot校园点歌系统
  • 15.<Spring Boot 日志>
  • 全流程安装DeepSeek开源模型
  • 深度学习|表示学习|卷积神经网络|Batch Normalization在干什么?|19
  • 【lua编程实操(一)】函数和闭包
  • 13.代理模式(Proxy Pattern)
  • mini-lsm通关笔记Week2Day7
  • 将OneDrive上的文件定期备份到移动硬盘
  • 闲聊邵雍的“象数”与古诗有感
  • 从51到STM32:PWM平滑迁移方案
  • make -j$(nproc)——多核加速编译
  • 《Java核心技术 卷II》本地日期
  • 01vue3实战-----前言
  • VSCode中使用EmmyLua插件对Unity的tolua断点调试