uva 10453 Make Palindrome(dp,最小回文生成)

来源:互联网 发布:什么是数据割接 编辑:程序博客网 时间:2024/06/05 09:36


dp[l][r]表示s[l]到s[r]这一段字符串生成回文的最小添加字符个数

决策:

1.若s[l]==s[r]

转移到dp[l+1][r-1]

2.若s[l]!=s[r]

在右部添加一个s[l]

转移到:dp[l+1][r]+1


在左部添加一个s[r]

转移到:dp[l][r-1]+1


需要打印最后结果,决策过程中保存路径,做得比较麻烦,对保存路程、输出决策过程不熟悉


#include<cstdio>#include<cstring>#include<stack>#include<queue>using namespace std;#define MAXN 1005char s[MAXN];int dp[MAXN][MAXN],path[MAXN][MAXN];int n;queue<char> q;stack<char> st;int min(int a,int b) {return a<b?a:b;}int dfs(int l,int r){if(l>r) return 0;if(dp[l][r]) return dp[l][r];int ans=MAXN;if(s[l]==s[r]){ans=min(ans,dfs(l+1,r-1));path[l][r]=1;}else{int temp1=dfs(l+1,r)+1,temp2=dfs(l,r-1)+1;if(ans>temp1){ans=temp1;path[l][r]=2;}if(ans>temp2){ans=temp2;path[l][r]=3;}}dp[l][r]=ans;return ans;}void out(){int l=0,r=n-1;while(l<=r){if(path[l][r]==1){if(l==r) st.push(s[l]);else{q.push(s[l]);st.push(s[r]);}l++;r--;}else if(path[l][r]==2){q.push(s[l]);st.push(s[l]);l++;}else if(path[l][r]==3){q.push(s[r]);st.push(s[r]);r--;}}while(!q.empty()){printf("%c",q.front());q.pop();}while(!st.empty()){printf("%c",st.top());st.pop();}printf("\n");}int main(){while(scanf("%s",s)!=EOF){n=strlen(s);for(int i=0;i<n;i++)for(int j=0;j<n;j++)dp[i][j]=path[i][j]=0;dfs(0,n-1);printf("%d ",dp[0][n-1]);out();}return 0;}


0 0
原创粉丝点击