首页 > 代码库 > POJ 1159 Palindrome(滚动数组)
POJ 1159 Palindrome(滚动数组)
链接:click here
题意:
给你一串字符串,让你求最少加入几个字符,才能使得这个字符串是个回文串。
思路:
设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);
如果直接求的话,会超时。
用两种解决方法:
1,shor int数组
2,运用动态数组。
根据dp滚动的过程我们可以知道,dp[]i][j]的值不会与dp[i-2][0.....n]的值有关系。
那么可以把dp[i][j]的值覆盖到dp[i-2][j]上。即dp[i][j]为dp[i%2][j];
代码:
<span style="font-size:12px;">#include <iostream> #include <stdio.h> #include <string.h> #define max(a,b) (a>b?a:b) using namespace std; const int maxn=5005; const int inf = 0x3f3f3f3f; short int dp[maxn][maxn]; int a[maxn],b[maxn]; int n,m,i,j,length; inline int input() { int res=0,f=1,c; while(!isdigit(c = getchar()) && c!='-'); c=='-' ? f=0 : res=c-'0'; while(isdigit(c = getchar())) res = res*10 + c-'0'; return f ? res : -res; } int main() { char str; //n=input(); //POJ 竟然不支持快速输入,写成这样返回WA scanf("%d",&n); getchar(); for(i=1; i<=n; i++) { scanf("%c",&str); a[i]=str; b[n-i+1]=str; } for(i=0; i<=n; i++) { dp[i][0]=0; dp[0][i]=0; } for(i=1; i<=n; i++) { for(j=1; j<=n; j++) { dp[i][j]=max(dp[i][j-1],dp[i-1][j]); if(a[i]==b[j]) { dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1); //关键 } } } length=dp[n][n]; printf("%d\n",n-length); //总长减去回文子长即为所求 return 0; } </span>
滚动数组:
<span style="font-size:12px;">#include <iostream> #include <stdio.h> #include <string.h> #define max(a,b) (a>b?a:b) using namespace std; const int maxn=5005; const int inf = 0x3f3f3f3f; short int dp[maxn][maxn]; int a[maxn],b[maxn]; int n,m,i,j,length; inline int input() { int res=0,f=1,c; while(!isdigit(c = getchar()) && c!='-'); c=='-' ? f=0 : res=c-'0'; while(isdigit(c = getchar())) res = res*10 + c-'0'; return f ? res : -res; } int main() { char str; //n=input(); scanf("%d",&n); getchar(); for(i=1; i<=n; i++) { scanf("%c",&str); a[i]=str; b[n-i+1]=str; } dp[1][0]=dp[0][0]=0; for(i=0; i<=n; i++) { //dp[i][0]=0; dp[0][i]=0; } for(i=1; i<=n; i++) { for(j=1; j<=n; j++) { dp[i%2][j]=max(dp[i%2][j-1],dp[(i-1)%2][j]); if(a[i]==b[j]) { dp[i%2][j]=max(dp[i%23][j],dp[(i-1)%2][j-1]+1); } } } length=dp[n%2][n]; printf("%d\n",n-length); return 0; } </span>
POJ 1159 Palindrome(滚动数组)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。