hdu1513 经典dp:添加最少字符使字符串回文:(滚动数组优化空间)
一开始写了个无脑递归,MLE了。。
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 char s[5005]; 6 int vis[5005][5005],n; 7 int dfs(int l,int r) 8 { 9 if (vis[l][r]) return vis[l][r]; 10 if (l==r) vis[l][r]=0; 11 else if (l+1==r) 12 { 13 if (s[l]==s[r]) vis[l][r]=0; 14 else vis[l][r]=1; 15 } 16 else{ 17 if (s[l]==s[r]) vis[l][r]=dfs(l+1,r-1); 18 else vis[l][r]=min(dfs(l+1,r),dfs(l,r-1))+1; 19 } 20 return vis[l][r]; 21 } 22 int main() 23 { 24 while (~scanf("%d",&n)) 25 { 26 getchar(); 27 for (int i=1;i<=n;i++) 28 scanf("%c",&s[i]); 29 memset(vis,0,sizeof(vis)); 30 printf("%d\n",dfs(1,n)); 31 } 32 return 0; 33 }
然后用滚动数组优化了下(要记录i-1位置的各个dp)
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 char s[5005]; 6 int dp[5005],temp[5005]; 7 int main() 8 { 9 int i,n,j; 10 while (~scanf("%d",&n)) 11 { 12 getchar(); 13 for (i=1;i<=n;i++) 14 scanf("%c",&s[i]); 15 memset(dp,0,sizeof(dp)); 16 for (i=1;i<=n;i++) 17 { 18 for (j=i;j>=1;j--) 19 temp[j]=dp[j]; 20 for (j=i-1;j>=1;j--) 21 if (i==j+1) { 22 if (s[j]==s[i]) dp[j]=0; 23 else dp[j]=1; 24 } 25 else{ 26 if (s[j]==s[i]) dp[j]=min(temp[j+1],min(temp[j],dp[j+1])+1); 27 else dp[j]=min(temp[j],dp[j+1])+1; 28 } 29 } 30 printf("%d\n",dp[1]); 31 } 32 return 0; 33 }