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

洛谷P8816 [CSP-J 2022] 上升点列一题的题解

20分

采用暴力搜索方法。使用深度优先搜索(DFS)进行遍历。对于每个点,有两种选择:将其加入序列或不加入序列。当遍历到第n个点时,对生成的序列进行合法性判断。

判断序列是否合法需满足两个条件:序列单调不减,且相邻两点之间的欧几里得距离为1(即一个点要么在另一个点的正上方,要么在正下方)。如果两点之间出现单调递减,则序列不合法;如果两点之间需要补充的点数超过k,同样不合法。

#include<bits/stdc++.h>usingnamespacestd;intn,k;vector<pair<int,int>>p;intmaxn=0;voidcheck(constvector<int>&c){if(c.empty())return;vector<pair<int,int>>cur;for(intidx:c){cur.push_back(p[idx]);}sort(cur.begin(),cur.end());//单调性的检查boolok=true;for(inti=1;i<cur.size();i++){if(cur[i].first<cur[i-1].first||cur[i].second<cur[i-1].second){ok=false;break;}}if(!ok)return;//计算需要添加的点数 d=(x2-x1)+(y2-y1)intcost=0;for(inti=1;i<cur.size();i++){intdx=cur[i].first-cur[i-1].first;intdy=cur[i].second-cur[i-1].second;cost+=(dx+dy-1);//需要补的点数}if(cost<=k){maxn=max(maxn,(int)c.size());}}voiddfs(intidx,vector<int>&c){if(idx==n){check(c);return;}dfs(idx+1,c);c.push_back(idx);dfs(idx+1,c);c.pop_back();}intmain(){cin>>n>>k;for(inti=0;i<n;i++){intx,y;cin>>x>>y;p.push_back({x,y});}vector<int>c;dfs(0,c);cout<<maxn+k;return0;}

100分法一

采用暴力搜索结合记忆化优化。由于DFS本身没有明显的记忆化点,因此将记忆化策略应用在check函数中。
我们知道,从一个点出发可以走很多条路,有一些路是有重叠的。所以可以记录每条路的子路的长度,到时候重叠部分直接用即可。

#include<bits/stdc++.h>usingnamespacestd;intn,k;vector<pair<int,int>>p;intmemo[505][505];intmaxn=0;intdfs(inti,intused)//used是之前补的点数{if(memo[i][used]!=-1)returnmemo[i][used];intbest=1;for(intj=i+1;j<n;j++){if(p[j].second<p[i].second)continue;//递减直接跳过intdx=p[j].first-p[i].first;intdy=p[j].second-p[i].second;intneed=dx+dy-1;if(used+need<=k){best=max(best,dfs(j,used+need+1);//找最长序列}}returnmemo[i][used]=best;//记忆化}intmain(){cin>>n>>k;for(inti=0;i<n;i++){intx,y;cin>>x>>y;p.push_back({x,y});}sort(p.begin(),p.end());memset(memo,-1,sizeof(memo));for(inti=0;i<n;i++){maxn=max(maxn,dfs(i,0));}cout<<maxn+k;return0;}

100分法二

暴力有一定风险,我们可以想想用dp。
实际上就是把记忆化数组变成dp数组就行了,只不过dp[i][0]要赋初值为1。策略:改在某个点往后探索为以该点结尾,中间某点开始到这里。但是used需要我们自己枚举,也充当dp[x][y]中的y。就是:从某点,此前花费used个点,下一个点接该点(不算补的点)的长度装进dp数组。

#include<bits/stdc++.h>usingnamespacestd;intn,k;vector<pair<int,int>>p;intdp[505][505];intmaxn=0;intmain(){cin>>n>>k;for(inti=0;i<n;i++){intx,y;cin>>x>>y;p.push_back({x,y});}sort(p.begin(),p.end());for(inti=0;i<n;i++){dp[i][0]=1;for(intj=0;j<i;j++){if(p[i].second<p[j].second)continue;intdx=p[i].first-p[j].first;intdy=p[i].second-p[j].second;intneed=dx+dy-1;for(intused=0;used+need<=k;used++){dp[i][used+need]=max(dp[i][used+need],dp[j][used]+1);}}}for(inti=0;i<n;i++){for(intused=0;used<=k;used++){maxn=max(dp[i][used],maxn);}}cout<<maxn+k;return0;}
http://www.jsqmd.com/news/1356532/

相关文章:

  • 脊髓横断面图像处理实战:从解剖结构到Python代码实现
  • 2026年8月呼和浩特市移动1000M宽带怎么选不踩坑 - 找卡家园
  • 拯救者工具箱终极指南:如何解锁联想游戏本隐藏性能与电池寿命
  • OpenRGB终极指南:一个免费软件统一控制所有RGB设备,告别厂商软件混乱
  • 深入解析-O3优化:从-O2升级的实战指南与性能陷阱
  • 第一次混沌演练把生产打挂 23 分钟:稳态定错、半径失控,4 个换来的规矩
  • 实时 AI 语伴如何切换大模型而不重做语音链路:统一适配、灰度路由与故障回退实战
  • 山海万灵 HarmonyOS 文化知识实战(19):MySQL、Redis、OpenSearch 与 MinIO 的内容发布同步
  • 基于User-Agent识别的Markdown数据接口爬虫实践与合规指南
  • Unity开发中Cursor编辑器代码提示失效的通用解决方案
  • 【单片机毕业设计推荐】基于 STM32 的室内环境空气质量监测与智能通风控制系统设计,基于 STM32 的多参数室内环境监测及联动报警系统设计(010106)
  • Python文本特征分析:从NLP基础到笔迹鉴定辅助系统构建
  • Claude Opus 4.7国内稳定接入全攻略:API调用、成本控制与IDE插件实战
  • VisualCppRedist AIO:一站式解决Windows C++运行库依赖的终极方案
  • 从明文泄漏到高价值漏洞的实战侦察与防御
  • AMD Ryzen处理器终极优化指南:RyzenAdj免费工具完整教程
  • 中文数字转阿拉伯数字:从“第一千三百六十四弹”解析到工程实践
  • 我在CSDN踩过的10个技术坑:血泪经验与避坑指南
  • A2A-Agent安全实战:从API Key到mTLS的认证鉴权指南
  • 本地部署AI图像生成模型:从Stable Diffusion环境搭建到API集成实践
  • 2026年8月杭州市移动500M宽带怎么选_新手避坑指南 - 找卡家园
  • ​现如今市场行情下:性价比高的证书有哪些?
  • Xss-labs-master 第10关
  • 如何用MediaCrawler一站式采集5大社交媒体数据:终极指南
  • 5分钟掌握PPTTimer:Windows上最智能的PPT演讲计时器终极指南
  • Docker构建低版本glibc编译环境:解决CentOS 7兼容性难题
  • NetLogo环境建模:社会网络仿真在生态研究中的应用
  • Log4net日志框架:核心架构与高级应用实践
  • 【RT-DETR涨点改进】AAAI 2026顶会 | 卷积创新改进篇 | 引入FAConv傅里叶分析卷积,适合红外—可见光图像融合、目标检测、小目标检测、图像增强任务,有效涨点
  • 2026年8月杭州市移动500M宽带避坑指南!小白怎么选_ - 找卡家园