最長公共上公升子串行(LCIS) 2016 7 14

2021-07-14 17:52:51 字數 3804 閱讀 6187

參考:

定義狀態

dp[i][j] 表示序列 a 與序列 b 的以 b[j] 結尾的 lcis 的長度

狀態轉移方程

①、若 a[i] != b[j],dp[i][j] = dp[i-1][j]

②、若 a[i] == b[j],dp[i][j] = max(dp[i-1][k]) + 1 (1 <= k < j && b[k] < b[j])

對於①:

dp[i][j] 是以 b[j]  為結尾的且 a[i] != b[j],所以 a[i] 對 dp[i][j] 沒有貢獻,必然有 dp[i][j] = dp[i-1][j]

對於②:

已知 a[i] == b[j],我們只要在前面找到乙個最長的且結尾小於 b[j]  的 lcis,然後將 b[j] 接到其後面就可以得到乙個以 b[j] 結尾的 lcis

時間複雜度的優化

可以發現,當 a[i] == b[j] 時,我們需要找到乙個 dp[i-1][k] 來取得最優解,且 b[k] < b[j],那麼必然有b[k] < a[i]

所以我們可以維護乙個 max  來儲存 dp[i-1][k] 的值,只要有 a[i] > b[j] 的地方就去嘗試更新這個最大值

也可以維護乙個 t 來儲存 k 的值

空間複雜度的優化

因為每次只需要用到 dp[i-1][j],所以可以優化到一維空間

hdu 1423 greatest common increasing subsequence

瞎搞了乙個 n ^ 4 解法竟然也可以過...資料貌似有點水

#include #include #include #include #include #include #include #include #include #include #include using namespace std;

typedef long long ll;

typedef unsigned long long ull;

typedef unsigned int uint;

const ull mod = 1e9 + 7;

const ll inf = 0x7ffffffff;

const int maxn = 500 + 10;

ll a1[maxn], a2[maxn];

ll dp[maxn][maxn];

ll b[maxn];

int main()

scanf("%d", &m2);

for (int i = 1; i <= m2; ++i)

a1[0] = a2[0] = -inf;

memset(dp, 0, sizeof(dp));

int max = 0;

for (int i = 1; i <= m1; ++i) }}

if (dp[i][j] > max) }}

}printf("%d\n", max);

if (t != 0)

}return 0;

}

#include #include #include #include #include #include #include #include #include #include #include using namespace std;

typedef long long ll;

typedef unsigned long long ull;

typedef unsigned int uint;

const ull mod = 1e9 + 7;

const int inf = 0x7fffffff;

const int maxn = 500 + 10;

int a1[maxn], a2[maxn];

int dp[maxn];

int main()

scanf("%d", &m2);

for (int i = 1; i <= m2; ++i)

memset(dp, 0, sizeof(dp));

for (int i = 1; i<= m1; ++i) else if (a1[i] > a2[j] && dp[t] < dp[j]) }}

int ans = 0;

for (int i = 1; i <= m2; ++i)

}printf("%d\n", ans);

if (t != 0)

}return 0;

}

poj 2127 greatest common increasing subsequence

解題思路:

如果題目要求列印路徑,應該用二維來做

因為一維存路徑的話,在乙個已經滿足上公升的序列中,可能會有後面的替換之前的前驅

63 6 9 12 4 6

53 4 6 9 12

比如這個序列,i = 3 6 9 12 的時候 dp = 1 0 2 3 4

4 到來的時候使之成為 1 2 2 3 4

這時候 6 再來,則改變了 6 原本位置上的前驅

這個 dp 的定義,可能會改變前驅,因為 dp[j] 只是以 j 為結尾而並沒有限制條件

#include #include #include #include #include #include #include #include #include #include #include using namespace std;

typedef long long ll;

typedef unsigned long long ull;

typedef unsigned int uint;

const ull mod = 1e9 + 7;

const int inf = 0x7fffffff;

const int maxn = 500 + 10;

int a1[maxn], a2[maxn];

int dp[maxn][maxn];

int pre[maxn][maxn];

int main()

scanf("%d", &m2);

for (int i = 1; i <= m2; ++i)

memset(pre, 0, sizeof(pre));

memset(dp, 0, sizeof(dp));

int max = 0;

int pos1 = 0, pos2 = 0;

for (int i = 1; i<= m1; ++i) else if (a1[i] > a2[j] && dp[i-1][t] < dp[i-1][j])

if (dp[i][j] > max) }}

printf("%d\n", max);

stackstack;

while (max != 0)

--pos1;

}if (!stack.empty())

while (!stack.empty())

printf("\n");

}return 0;

}

LCIS 最長公共上公升子串行

1004 tyvj1071 lcis最長公共上公升子串行 description 熊大媽的奶牛在小沐沐的薰陶下開始研究資訊題目。小沐沐先讓奶牛研究了最長上公升子串行,再讓他們研究了最長公共子串行,現在又讓他們要研究最長公共上公升子串行了。小沐沐說,對於兩個串a,b,如果它們都包含一段位置不一定連續的...

LCIS (最長公共上公升子串行)

ac通道 題目含義就是求最長公共上公升子串行 首先考慮,最長公共上公升子串行 最長上公升子串行 最長公共子串行,可以通過lis和lcs的思想去考慮本題目。定義狀態 dp i j 表示a陣列的前i個和b陣列的前j個且以b j 結尾的lcis長度考慮狀態轉移 轉移有兩種情況 a i b j 時候的轉移,...

最長公共上公升子串行(LCIS)

題解熊大媽的奶牛在小沐沐的薰陶下開始研究資訊題目。小沐沐先讓奶牛研究了最長上公升子串行,再讓他們研究了最長公共子串行,現在又讓他們研究最長公共上公升子串行了。小沐沐說,對於兩個數列a和b,如果它們都包含一段位置不一定連續的數,且數值是嚴格遞增的,那麼稱這一段數是兩個數列的公共上公升子串行,而所有的公...