问题:
给定两个数组A,B
若两个数组存在相同的数,则画一条连线,使得所画连线不得相交,最多能画多少条?
Example 1: Input: A = [1,4,2], B = [1,2,4] Output: 2 Explanation: We can draw 2 uncrossed lines as in the diagram. We cannot draw 3 uncrossed lines, because the line from A[1]=4 to B[2]=4 will intersect the line from A[2]=2 to B[1]=2. Example 2: Input: A = [2,5,1,2,5], B = [10,5,2,1,5,2] Output: 3 Example 3: Input: A = [1,3,7,1,7,5], B = [1,9,2,5,1] Output: 2 Note: 1 <= A.length <= 500 1 <= B.length <= 500 1 <= A[i], B[i] <= 2000
解法:
DP动态规划:
dp[i][j]:代表截止到A[i] B[j],最多能画的连线条数。
动态转移方程:
1. 选择连上A[i] B[j]:
则当且仅当:A[i]==B[j],这时,dp[i][j]=dp[i-1][j-1]+1 :截止到A[i-1] B[j-1]最多能画的连接条数+1
2. 选择不连A[i] B[j]:
A[i]!=B[j] ,这时,dp[i][j]=max(dp[i][j-1], dp[i-1][j]):那么A[i]可以连到B[i-1]以前的任意,B[j]可以连到A[i-1]以前的任意。那就求
截止到A[i] B[j-1] 或者 截止到A[i-1] B[j] 最多能画的连接条数 二者的最大。
初始状态:
A[0]B[j]:(A[i]==B[j]时)dp[0][j]=0+1(A[i]!=B[j]时)dp[0][j]=0
A[i]B[0]:(A[i]==B[j]时)dp[i][0]=0+1(A[i]!=B[j]时)dp[i][0]=0
由于计算方法可以合并,可以往前多加一位全为0,dp[0][j]或者dp[i][0]都=0
dp[1][j],从A[0]开始判断。
dp[i][1],从B[0]开始判断。
代码参考:
1 class Solution { 2 public: 3 int maxUncrossedLines(vector<int>& A, vector<int>& B) { 4 int n=A.size(), m=B.size(); 5 int dp[n+1][m+1]; 6 memset(dp, 0, sizeof(dp)); 7 for(int i=1; i<=n; i++){ 8 for(int j=1; j<=m; j++){ 9 if(A[i-1]==B[j-1]){ 10 dp[i][j]=dp[i-1][j-1]+1; 11 }else{ 12 dp[i][j]=max(dp[i-1][j], dp[i][j-1]); 13 } 14 } 15 } 16 return dp[n][m]; 17 } 18 };