C++ 中的无交叉线
假设我们在两条独立的水平线上写下了数组 A 和 B 的整数(按照给定的顺序)。现在,我们可以画连接线:一条连接两个数字 A[i] 和 B[j] 的直线,条件是 -
A[i] == B[j];
我们绘制的线不与任何其他连接线(非水平线)相交。
我们必须记住,连接线即使在端点处也不能相交 - 每个数字只能属于一条连接线。找到连接线的最大数量。因此,如果输入类似于 [1,4,2] 和 [1,2,4],则输出将为 2。
1 | 4 | 2 |
1 | 2 | 4 |
我们可以在图中绘制 2 条无交叉线。我们无法绘制 3 条无交叉线,这是因为从 A[1]=4 到 B[2]=4 的线将与从 A[2]=2 到 B[1]=2 的线相交。
为了解决这个问题,我们将遵循以下步骤 -
定义一个名为 solve() 的方法,它将接收 i、j、数组 A、数组 B 和矩阵 dp
如果 i 超出数组 A 的范围,则返回 0
如果 j 超出数组 B 的范围,则返回 0
nj := j
当 nj < B 的大小且 B[nj] 不等于 A[i] 时
将 nj 增加 1
当 nj < B 的大小时,temp := 1,否则为 0
ret := (solve(i + 1, j, A, B, dp) 和 temp) 以及 solve(i + 1, nj + 1, A, B, dp) 的最大值
dp[i, j] := ret 并返回 ret
从主方法
n := A 的大小,m := B 的大小
创建一个大小为 n x m 的矩阵 dp,并将其填充为 – 1
调用 solve(0, 0, A, , dp)
让我们看看以下实现以获得更好的理解 -
示例
#include <bits/stdc++.h> using namespace std; class Solution { public: int solve(int i, int j, vector <int>&A, vector <int>&B, vector < vector <int> >& dp){ if(i >= A.size()) return 0; if(j >= B.size()) return 0; if(dp[i][j] != -1) return dp[i][j]; int nj = j; while(nj < B.size() && B[nj] != A[i]) nj++; int ret = max(solve(i + 1, j, A, B, dp), (nj < B.size() ? 1 : 0) + solve(i + 1, nj + 1, A, B, dp)); return dp[i][j] = ret; } int maxUncrossedLines(vector<int>& A, vector<int>& B) { int n = A.size(); int m = B.size(); vector < vector <int > > dp(n, vector <int>(m, -1)); return solve(0, 0, A, B, dp); } }; main(){ vector<int> v1 = {1,4,2}; vector<int> v2 = {1,2,4}; Solution ob; cout << (ob.maxUncrossedLines(v1, v2)); }
输入
[1,4,2] [1,2,4]
输出
2
广告