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...