POJ1159迴文字串(DP+滾動陣列)
阿新 • • 發佈:2019-02-14
題目的大概意思就是給你一個字串,讓你在任意位置新增任意字元讓它變成一個迴文字串,求最少新增的字元數。
這是一道典型的DP,總體思路就是把逆串搞出來,兩個字串求出一個最大公共子序列的長度,然後拿n減去這個長度就可以了。
一開始想直接開二維的DP陣列,結果發現5000的長度會爆。網上學了用一個滾動陣列,因為當前狀態只與上一狀態有關,而且再先前的狀態(上上狀態)沒有儲存的意義。所以注意到0與1這兩個數字能用1-x來進行互相轉換,所以能大大節省記憶體的空間。以後感覺可能很有用。
程式碼如下:
//#include <bits/stdc++.h> #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; char str1[5005],str2[5005]; int maxlen[2][5005]; int main() { int n; //freopen("de.txt","r",stdin); while (~scanf("%d",&n)) { for (int i=1;i<=n;++i) { cin>>str1[i]; str2[n+1-i]=str1[i]; } str1[n+1]='\0'; str2[n+1]='\0'; memset(maxlen,0,sizeof maxlen); int e=0;//利用1-x,當x=0時1-x=1;x=1時1-x=0; for (int i=1;i<=n;++i) { e=1-e;//當前狀態是e,有上一個狀態1-e得出; for (int j=0;j<=n;++j) { if (str1[i]==str2[j]) maxlen[e][j]=maxlen[1-e][j-1]+1;//相當於maxlen[i][j]=maxlen[i-1][j-1]+1 else maxlen[e][j]=max(maxlen[e][j-1],maxlen[1-e][j]);//相當於maxlen[i][j]=max(maxlen[i][j-1],maxlen[i-1][j]) } } cout<<n-maxlen[e][n]<<endl;//處理完成後當前狀態是e,所以輸出的是maxlen[e][n] } return 0; }
我看見還有200多MS過的,可能是演算法不一樣吧。另外吐槽一句,POJ不認#include <bits/stdc++.h>,交了2發CE....