核心**:
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 bit[maxn],v[maxn],a[maxn],l[maxn];
int lowbit(int x)
void add(int x,int d)
int main()
len=unique(v+1,v+1+n)-v-1;
for(int i=1;i<=n;i++)
for(int i=1;i<=n;i++)
printf("\n");
}return
0;}
以上**可以用滾動陣列進行空間優化
解析:f[i][j]表示以b[j]結尾,字串a[i]之前的公共上公升子串行最大長度;
顯然:f[i
][j]
>=f[
i−1]
[j];
f [i
][j]
>=f[
i−1]
[j];
遞推:若a[
i]!=
b[j]
:f[i
][j]
=f[i
−1[j
];a [i
]!=b
[j]:
f[i]
[j]=
f[i−
1[j]
;若a[
i]==b
[j]:
f[i]
[j]=
max a[i
]==b[
j]:f
[i][
j]=m
ax
(f[k][j])+1;(
1<=
k 1
<=
k<=j-1&&b[
j]>b[
k]b [j
]>b[
k]
) 核心**
for(int i=1;ifor(int j=1;jif(a[i]!=b[j])f[i][j]=f[i-1][j];
else
f[i][j]=mn+1;
ans=max(f[i][j],ans);}}
}
核心**:
優化:通過記錄對於當前a[i]與b[1-m]的匹配過程中的最大上公升子串行mm,邊記錄,邊更新,降低一維
for(int i=1;iint mm=0;
for(int j=1;jif(a[i]>b[j])mm=max(mm,f1[j]);//優化
else
if(a[i]==b[j])
f1[j]=mm+1,ans2=max(ans2,f1[j]);
}}
測試源程式:
#include
#include
#include
#include
using
namespace
std;
int main()
else}}
memset(f,0,sizeof f);
int ans=0;
for(int i=1;ifor(int j=1;jif(a[i]!=b[j])f[i][j]=f[i-1][j];
else
f[i][j]=mn+1;
ans=max(f[i][j],ans);}}
}memset(f1,0,sizeof f1);
int ans2=0;
for(int i=1;iint mm=0;
for(int j=1;jif(a[i]>b[j])mm=max(mm,f1[j]);
else
if(a[i]==b[j])
f1[j]=mm+1,ans2=max(ans2,f1[j]);}}
cout
<<"最長上公升子串行:"
<1][m-1]<<"最長公共上公升子串行n*n*n:"
<<"最長公共上公升子串行n*n:"
0;}
最長上公升子串行 最長公共上公升子串行
求最長公共子串行有幾種方法 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...
演算法 動態規劃 最長公共子串行,最長上公升子串行
最長公共子串行 動態規劃 最長公共子串行 時間複雜度 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...
最長上公升子串行
問題描述 乙個數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列 a1,a2,an 我們可以得到一些上公升的子串行 ai1,ai2,aik 這裡1 i1 i2 ik n。比如,對於序列 1,7,3,5,9,4,8 有它的一些上公升子串行,如 1,7 3,4,8 等等...