標籤:style color 使用 strong 資料 io
1、先說說杭電的1159吧!
這道題是基礎動規,比較簡單!
就是要你求最長的公用子序列(不要最佳化)
動態轉移方程: dp[i+1][j+1]=(a[i]=b[i])?dp[i][j]+1:max(dp[i+1][j],dp[i][j+1])
AC代碼:
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define N 520char a[N],b[N];int dp[N][N];int main(){ int i,j,len_a,len_b; while(scanf("%s %s",a,b)!=EOF) { len_a=strlen(a); len_b=strlen(b); for(i=1;i<=len_a;i++) for(j=1;j<=len_b;j++) { if(a[i-1]==b[j-1]) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); } printf("%d\n",dp[len_a][len_b]); } return 0;}
2、再說POJ1159:
題意是給你一個字串,要你算出它成為迴文串需要多少字母
Ab3bddb3bA本質為求字串及其逆序串的最長公用子序列(LCS)
如果你還想用剛剛那方法,不好意思,空間複雜度為5K*5K;果斷送給了POJ1個
Memory Limit Exceeded!之前學了個滾動數組來最佳化空間,現在可以考慮了滾動數組最佳化空間複雜度
注意到dp[i][j]只和dp[i-1][j-1],dp[i-1][j],dp[i][j-1]三個值相關,我們可以只保留兩行的資料即可,這樣使用兩個數組滾動計算即可所以,AC代碼:
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define N 5005int dp[2][N];char str[N],cstr[N];int main(){ int i,j,t; scanf("%d",&t); scanf("%s",str); for(i=0;i<t;i++){ cstr[i]=str[t-i-1]; dp[0][i]=dp[1][i]=0; } dp[0][t]=dp[1][t]=0; for(i=1;i<=t;i++) for(j=1;j<=t;j++) { if(str[i-1]==cstr[j-1]) dp[i%2][j]=dp[(i-1)%2][j-1]+1; else dp[i%2][j]=max(dp[(i-1)%2][j],dp[i%2][j-1]); } printf("%d\n",t-dp[t%2][t]); return 0;}