動態規劃(最長公共序列,最長上公升序列)

2021-10-01 14:17:03 字數 1545 閱讀 2732

在牛客網上刷面經的過程中,發現面試常問的兩道題,這裡記錄下來,方便以後複習檢視。

並分別在 poj  1458

2533   ac!

#include#include

#include

#define n 1005

using

namespace

std;

intdp[n][n];

/*dp[i][j]表示 p1[1...i]與 p2[1...j]的最長公共子串行lcs

初始狀態:某乙個排列為空,那麼lcs肯定為0,故很容易推斷出 dp[0][1..n]=0, dp[1..n][0]

1、if p1[n]==p2[n],則 dp[n][n]=dp[n-1][n-1] + 1

2、if p1[n]!=p2[n], 則 dp[n][n] = max(dp[n][n-1], dp[n-1][n])

tips:

為了提高效率,採用自底向上計算的方法。

也即先計算dp[1][1]... 最後計算dp[n][n],因為dp[n][n]肯定要用到之前的狀態嘛

*/int solve(string p1, string p2, int p1_len, int

p2_len)

else}}

return

dp[p1_len][p2_len];

}int

main()

return0;

}

#include#include

#include

#include

#define n 1005

using

namespace

std;

intp1[n];

intn;

intdp[n];

/*dp[i]表示 p[0...i] 的最長上公升子串行 lis **中solve_1

方法一 : 直接dp,o(n^2)

1、dp[0] = 1

2、dp[i] = max(dp[i], dp[j]) + 1, 0<=jp[j](因為只有大於才是上公升的序列)

方法二 :貪心 + 二分,o(nlogn) **中solve_2

貪心:對於固定某一長度lis而言,最後乙個數字越小,越有可能新增新元素

如長度為2的lis比好!

1、我們維護乙個dp陣列, dp[i]表示p[0..i]這個長度為i+1的序列 lis最小值

2、利用二分查詢找到位置,並插入之

3、最後結果即為dp陣列的長度

*/int solve_1(int p1, int

p1_len)

for(int i=0;i)

ans =max(ans, dp[i]);

}return

ans;

}int solve_2(int p1, int

p1_len)

else

}return pos+1;}

intmain()

//coutreturn0;

}

演算法 動態規劃 最長公共子串行,最長上公升子串行

最長公共子串行 動態規劃 最長公共子串行 時間複雜度 o n n include include include include using namespace std const int n 1010 int dp n n char s n t n int main printf d n dp s...

最長公共子串行 最長上公升子串行 最長公共上公升子串行

核心 for int i 1 ifor int j 1 jif a i b j else hdu5248 樹狀陣列優化 nl ogn nlo gn include using namespace std const int maxn 100005 char a maxn int len int bi...

最長上公升子串行 最長公共上公升子串行

求最長公共子串行有幾種方法 include include using namespace std include include const int inf 0x3f3f3f3f const int maxn 10005 int a maxn ints maxn int dp maxn int d...