【算法提高课】AcWing1012.友好城市 长期攻克提高课-day8(8/219)

题目的描述

1、朴素版题意描述

背景设定

Palmia 国东西走向的大河分南北两岸,两岸各分布 N 个坐标互不重复的城市;北岸每个城市唯一对应南岸一个友好城市,配对关系两两不重复。每一对友好城市申请修建一条跨河直线航道,要求获批的航道任意两条都不能交叉,需要挑选尽可能多的航道通过审批,求最多可批准的航道条数。

输入规则

  1. 首行输入整数 N,代表城市总对数;
  2. 后续 N 行,每行输入两个整数,依次为一组友好城市里南岸坐标、北岸坐标。

任务要求

输出满足航道互不交叉前提下,最多能批准的申请数量。

2、数学描述

1. 符号定义

设共有N组友好城市配对,构造配对集合:

T={(si,ni), i=1,2,...,N}T=\{(s_i,n_i),\ i=1,2,\dots,N\}T={(si,ni), i=1,2,...,N}

  • sis_isi:第i组配对的南岸城市横坐标,所有sis_isi取值互异;
  • nin_ini:第i组配对的北岸城市横坐标,所有nin_ini取值互异; 配对映射si↦nis_i \mapsto n_isi↦ni为一一映射。

2. 约束条件

选取子集T′⊆TT'\subseteq TT′⊆T,对T′T'T′内任意两组不同配对(sa,na),(sb,nb)(s_a,n_a),(s_b,n_b)(sa,na),(sb,nb),二者连接而成的线段(航道)无交点。

3. 优化目标

最大化子集T′T'T′包含的元素个数∣T′∣|T'|∣T′∣,输出该最大数值。

3、数据范围

1≤N≤5000,1≤N≤5000,1≤N≤5000,

0≤xi≤100000≤x_i≤100000≤xi≤10000

题目的分析

我们先上结论,再上证明。

1、结论

  1. 输入N组坐标:每组依次给出南岸城市横坐标、北岸友好城市横坐标;
  2. 先按南岸城市坐标从小到大所有配对排序
  3. 排序后提取对应北岸城市的坐标序列,问题等价于 找这个序列里最长上升子序列的长度:
    • 南岸坐标递增排布时,北岸坐标也单调递增,航道就不会交叉;北岸坐标递减则航道交叉;
  4. 最长上升子序列的长度就是最多可批准的航道数量。

2、证明

大河水平延伸,南岸在下、北岸在上,横坐标从左到右增大(越靠右 x 坐标越大):

  • 南岸点记S、北岸点记N,一对友好城市连线段SN就是航道;
  • 取两组航道:航道 1(Sa,Na)(S_a,N_a)(Sa,Na)、航道 2(Sb,Nb)(S_b,N_b)(Sb,Nb),强制约束SaS_aSa在南岸左侧、SbS_bSb在南岸右侧,即sa<sb\boldsymbol{s_a < s_b}sa<sb(南岸横坐标严格左小右大),只分两种北岸位置情况画图对比。

情况1:sa<sbs_a<s_bsa<sb且na<nbn_a<n_bna<nb(北岸左小右大)

南岸靠左的城市连北岸靠左城市,南岸靠右的城市连北岸靠右城市,线段走向一致,不会相交

情况2:sa<sbs_a<s_bsa<sb且na>nbn_a>n_bna>nb(北岸左大右小)

南岸靠左的点连北岸靠右的点、南岸靠右的点连北岸靠左的点,线段必然相交。

严格逻辑证明(结合图形结论)

步骤 1:排序固定南岸顺序

把所有配对按南岸横坐标升序重排,得到固定顺序:

s1<s2<s3<⋯<sNs_1<s_2<s_3<\dots<s_Ns1<s2<s3<⋯<sN 此时只需观察对应北岸序列 A={n1,n2,...,nN}A=\{n_1,n_2,\dots,n_N\}A={n1,n2,...,nN}的大小关系。

步骤 2:多选航道的无交叉约束

若同时选中下标i<ji<ji<j的两条航道,天然满足si<sjs_i<s_jsi<sj; 由图形结论:想要航道不交叉,必须强制ni<njn_i<n_jni<nj。 推广到多条航道:选中一批下标i1<i2<⋯<iki_1<i_2<\dots<i_ki1<i2<⋯<ik,全部两两无交叉  ⟺  \iff⟺

ni1<ni2<⋯<nikn_{i_1}<n_{i_2}<\dots<n_{i_k}ni1<ni2<⋯<nik 这恰好就是上升子序列的定义。

步骤 3:最大值等价结论

题目要求选中航道数量最多,等价于找满足下标递增、数值递增的最长子序列,即序列A的最长上升子序列 (LIS) 长度

3、闫氏DP分析法

我们可以从上方的结论得到,这道题本质还是最长上升子序列,只不过要固定南岸的自变量,即:把所有城市配对按南岸坐标sis_isi从小到大排序 ,南岸坐标成为严格递增的自变量,顺序完全锁定,不会变动;此时每组配对唯一对应一个北岸坐标nin_ini,得到一维序列{n1,n2,...,nN}\{n_1,n_2,\dots,n_N\}{n1,n2,...,nN}。

所以,我们就把这道题转换成求"自变量"固定后的"因变量"的最长上升子序列

首先根据经验,这种题一般只有一维状态

我们可以设:dpidpidpi

集合:所有朝同一方向且以nin_ini结尾的上升子序列的集合

属性:Max

即:所有朝同一方向且以nin_ini结尾的上升子序列的长度集合的最大值

然后状态计算,开始划分集合,我们以最后一个集合dpi来划分

显然集合可以划分为从{dp0,dp1,dp2,...,dpi−1}\{dp0,dp1,dp2,...,dpi-1\}{dp0,dp1,dp2,...,dpi−1}到达dpidpidpi的所有长度(要满足:nj<ni,j∈{j∣0≤j<i}n_j<n_i,j∈\{j|0≤j<i\}nj<ni,j∈{j∣0≤j<i}),因为dpidpidpi的定义是以nin_ini结尾的最长上升子序列的长度,因此dpi=max({dp0,dp1,dp2,...,dpi−1})+1,(nj<ni,j∈{j∣0≤j<i})dpi=max(\{dp0,dp1,dp2,...,dpi-1\})+1,(n_j<n_i,j∈\{j|0≤j<i\})dpi=max({dp0,dp1,dp2,...,dpi−1})+1,(nj<ni,j∈{j∣0≤j<i}),即:dpi=max⁡{dpj+1∣0≤j<i, nj<ni}dpi = \max\big\{dpj + 1 \mid 0 \le j < i,\ n_j < n_i\big\}dpi=max{dpj+1∣0≤j<i, nj<ni},这也是我们本次动态规划的状态转移方程。

即:dpi=max⁡{dpj+1∣0≤j<i, nj<ni}dpi = \max\big\{dpj + 1 \mid 0 \le j < i,\ n_j < n_i\big\}dpi=max{dpj+1∣0≤j<i, nj<ni}

闫氏DP分析图

题目的代码

**题目地址:**https://www.acwing.com/problem/content/1014/

cpp 复制代码
#include <iostream>
#include <algorithm>

using namespace std;

typedef pair<int, int> PII;

const int N = 5010;

int n;
PII city[N];
int f[N];

int main()
{
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ) 
        scanf("%d%d", &city[i].first, &city[i].second);
    // 最重要的一步排序,按照pair自带排序规则,先排first,若first相等再排second
    sort(city, city + n);

    int res = 0;
    for (int i = 0; i < n; i ++ )
    {
        f[i] = 1;
        for (int j = 0; j < i; j ++ )
            // 根据"因变量"找到最长上升子序列的长度
            if (city[i].second > city[j].second)
                f[i] = max(f[i], f[j] + 1);
        res = max(res, f[i]);
    }
    // 输出最多能批准的申请数量
    printf("%d\n", res);

    return 0;
}

时间复杂度: O(n2)O(n^2)O(n2)

空间复杂度: O(n)O(n)O(n)

相关推荐
地平线开发者12 小时前
【模型轻量化专题】衡量模型轻量性的指标
算法
学习星球15 小时前
OFDM技术精讲:正交性推导、循环前缀原理与80行Python链路仿真(附实测数据)
算法·面试·前端框架
alphaTao21 小时前
LeetCode 每日一题 2026/8/24-2026/8/30
python·算法·leetcode
Interview Aid11221 小时前
TikTok OA 四题分享|半小时内 AC,题目基本都是实现题
java·开发语言·算法·面试·职场和发展
顶点多余1 天前
那些在算法中适合巩固的知识点---1
java·前端·算法
罗西的思考1 天前
【Agentic RL / 强化学习框架】Molt 设计解读
人工智能·算法·机器学习
hahaha60161 天前
HLS高层次综合设计技巧--C++类和模板
图像处理·人工智能·算法·计算机视觉
多弗朗皮卡丘1 天前
算法详解4:买卖股票的最佳时机系列(上)
算法
维克兜率天1 天前
【维克】动量指标家族:RSI、ROC、CCI、Momentum全面解析
python·算法
AI情绪识别开源2 天前
检信 AI 智能推广平台(代号:JX-Promote)
人工智能·算法·erlang