之前求過lis和lcs,這次求兩者的綜合問題。那麼就需要用到這兩個問題的思想。
首先,用dp[i][j]表示str1和str2分別以i和j結尾的lcis,那麼對於str1[i] == str2[j]的時候,就要在1~j-1之間找到最優解,就是滿足條件dp當中最大的乙個,這個就是lis的思想。如果不等的時候順便更新一下小於str1[i]的dp最大的str2[j],這樣的話在更新str1[i] == str2[j] 的時候就用o(1)的時間就能更新了。
當然,如果光求lcis的長度的話,可以省略掉一維的空間,但是時間還是o(nm)
hdu 1423
#include #include#include
using
namespace
std;
const
int maxn =550
;int
s1[maxn], s2[maxn];
intdp[maxn];
int lcis(int n, int
m) }
int ans = 0
;
for (int i = 1; i <= m; i++) ans =max(ans, dp[i]);
return
ans;
}int
main()
return0;
}
比較複雜一點的就是求路徑的,就是求出這個lcis序列
zoj 2432
#include #include#include
using
namespace
std;
const
int maxn =550
;int
s1[maxn], s2[maxn];
intdp[maxn][maxn];
struct
path path[maxn][maxn];
intr;
int lcis(int n, int
m)
if (s1[i] >s2[j])
if (dp[i][k] }
}int ans = 0
;
for (int i = 1; i <= m; i++)
if (ans return
ans;
}int p[maxn * 2
];void print(int
n)
for (int i = cnt - 1; i >= 0; i--)
printf(
"%d
", p[i]);
puts(
"");
}int
main()
return0;
}
關於lcs的應用
給定乙個字串,讓求最少新增多少個字元使得成為回文串。
思路:因為回文字串是對稱的,所以把回文字串反過來和它本身求lcs,求出來還是它本身,所以,把原來的字串反過來和它求lcs,那麼求出來之後的長度就說明裡買能已經存在的回文串長度,剩下的長度就是需要新增的長度。
#include #include#include
using
namespace
std;
const
int maxn = 1100
;char
s1[maxn], s2[maxn];
intdp[maxn][maxn];
intmain()}}
printf(
"%d\n
", len -dp[len][len]);
}return0;
}
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,如果它們都包含一段位置不一定連續的數,且數值是嚴格遞增的,那麼稱這一段數是兩個數列的公共上公升子串行,而所有的公...