POJ 1159滾動陣列

2021-06-26 12:07:08 字數 1198 閱讀 3415

題意:

給你一串字串,讓你求最少加入幾個字元,才能使得這個字串是個回文串。

做法:設a[i]是這個字串,b[i]是這個字串的逆序串。

那麼a[i],b[i]的最長公共子串行就是所求的字串裡擁有的最大的回文串。

然後用總串長減去最大的回文串長度即為所求。

求最長公共子串行的公式為:

dp[i][j]=max(dp[i-1] [j],dp[i][j-1])

if(a[i]==b[i])

dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);

如果直接求的話,勢必要開乙個5001*5001的陣列,鐵定mle。

有一下兩種解決方法:

1,開short int型陣列

這是poj返回的結果:

2,運用動態陣列。

根據dp滾動的過程我們可以知道,dp【i】【j】的值不會與dp[i-2][0.....n]的值有關係。

那麼可以把dp[i][j]的值覆蓋到dp[i-2][j]上。即dp[i][j]為dp[i%2][j];

poj返回的結果:

對比以上兩種方法,顯而易見的可以得出2的方法很節約空間,就是耗時略長。

1 short int 陣列

#include#include#include#define max(a,b) (a>b?a:b)

using namespace std;

short int dp[5001][5001];

int main()

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

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

int len;

len=dp[n][n];

printf("%d\n",n-len);

return 0;

}

2.2,滾動陣列

#include#include#includeusing namespace std;

int main()

dp[1][0]=dp[0][0]=0;

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

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

int len;

len=dp[n%2][n];

printf("%d\n",n-len);

return 0;

}

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

POJ 1159 如何構造回文序列

poj1159 給定乙個字串str,問最少需要新增多少個字串能使得str變成回文串?該問題是最長公共子串行的問題的延伸。字串 str 長度為 n,字串的逆串 istr。他們的最長公共子串行的長度 l lcs str,istr 公共子串行中的元素不需要新增對稱,剩餘的元素需要新增一元素使其對稱。所以最...

poj1159 dp 滾動陣列

如題 給出乙個字串和它的長度,要求輸出最少要加幾個字母這個字串變成回文串。增加回文串的數量 字串長度 字串和它的逆序的最長公共子串行的長度。字串長5000 如果開dp肯定超記憶體,可以使用short定義陣列。不難發現,dp的狀態轉移方程dp i j max dp i 1 j dp i j 1 或dp...