題意:
給你一串字串,讓你求最少加入幾個字元,才能使得這個字串是個回文串。
做法:設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 陣列
2.2,滾動陣列#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;
}
#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...