POJ 1159 如何構造回文序列

2021-06-18 10:11:18 字數 1594 閱讀 8486

poj1159

給定乙個字串str, 問最少需要新增多少個字串能使得str變成回文串?該問題是最長公共子串行的問題的延伸。

字串  str  長度為 n,  字串的逆串  istr。他們的最長公共子串行的長度 l = lcs(str, istr)。公共子串行中的元素不需要新增對稱,剩餘的元素需要新增一元素使其對稱。

所以最少需要新增的字串的數目 min = n - l。

lcd[ m ][ n ]長度為m, n的兩個字串的最長公共子串行的長度。a[0, m-1], b[0, n-1] 兩個字串的形式化表示。

a[m-1] == b[n-1]    該種情況下lcd[m][n] 只有乙個子問題

lcd[m][n] = lcd[m-1][n-1] + 1;  

a[m-1] != bn-1     該種情況下該種情況下lcd[m][n] 有兩個子問題

lcd[m][n] = lcd[m][n-1] ;   lcd[m][n] = lcd[m-1][n] ;  子問題的選擇也很明確:選擇最大的子問題。

lcd[0 ... m][0] =

for (i = 1; i < m; i++)

for (j = 1; j < n; j++)

if  

str[i] == istr[j]  

lcd[i][j] = lcd[i - 1][j - 1] + 1

else

lcd[i][j] = 

max

#include#includeusing namespace std;

static int n;

static const int n = 5001;

static char str[n];

static char rstr[n];

static int c[n][n];

//#define debug

int lcs() }

return c[n][n];

}int main()

rstr[i]= '\0';

cout << n - lcs() << "\n";

return 0;

}

上面**的記憶體使用超限了,需要進行優化。

#include#includeusing namespace std;

#define n 5001

static char str[n];

static char rstr[n];

static int c[2][n];

//#define debug

/*296k 766ms

*/int main()

rstr[i]= '\0';

for (i = 1; i <= n; i++)

}cout << n - c[(i - 1) % 2][j - 1] << "\n";

} return 0;

}

優化後的**,使用輪換陣列代替整個動態規劃表使用空間大大減少。該題要經常複習,該題和poj 1745處理方式類似。

poj1159

POJ 1159滾動陣列

題意 給你一串字串,讓你求最少加入幾個字元,才能使得這個字串是個回文串。做法 設a i 是這個字串,b i 是這個字串的逆序串。那麼a i b i 的最長公共子串行就是所求的字串裡擁有的最大的回文串。然後用總串長減去最大的回文串長度即為所求。求最長公共子串行的公式為 dp i j max dp i ...

POJ 1159 回文LCS滾動陣列優化

詳細解題報告可以看這個ppt 這題如果是直接開int 5000 5000 的空間肯定會mle,優化方法是採用滾動陣列。原lcs轉移方程 dp i j dp i 1 j dp i j 1 因為 dp i j 只依賴於 dp i 1 j 和 dp i j 1 所以可以採用滾動陣列如下 dp i 2 j ...

動態規劃經典 最長公共子串行 poj1159

出處 幫我稍微理解了這個思想。哎 我就是傳說中的無腦兒啊!乙個序列x,乙個序列y,x的下標用i,y的下標用j,xi表示從第乙個元素到第i個元素的這個序列。yj表示從第乙個元素到第j個元素的序列。xi表示x序列的第i個元素,yj表示y序列的第j個元素。我們把序列xn和ym的最長公共子串行的長度表示為f...