zoukankan      html  css  js  c++  java
  • [POJ1159]Palindrome

    题目大意:给你一个字符串(区分大小写),要求你添加最少的字符使其变成回文串,问最少添加几个字符。

    思路:此题的答案=原字符串长度-原字符串与前后颠倒后的字符串的最长公共子串长度(LCS)。

    求LCS用DP。

    此题字符串最长能达5000,数组需要开5000*5000*int,会“炸”(MLE)。解决办法:①用short;②用滚动数组。

    下面是两者的对比(上面是方法①,下面是方法②): 

    由此可见,方法②完胜方法①(尤其是内存,相差49028K!)。(不会滚动数组的使用方法①也是个选择)

    C++ Code:

    方法①:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    char a[5005],b[5005];
    int dp[2][5005];
    int l;
    int main(){
    	while(scanf("%d",&l)!=EOF){
    		memset(a,0,sizeof(a));
    		a[0]='^';
    		scanf("%s",a+1);
    		strcpy(b,a);
    		memset(dp,0,sizeof(dp));
    		reverse(b+1,b+l+1);
    		int Max=0;
    		for(int i=1;i<=l;i++)
    		for(int j=1;j<=l;j++){
    			if(a[i]==b[j])dp[i%2][j]=dp[(i-1)%2][j-1]+1;
    			else
    			dp[i%2][j]=max(dp[i%2][j-1],dp[(i-1)%2][j]);
    			if(Max<dp[i%2][j])Max=dp[i%2][j];
    		}
    		printf("%d
    ",l-Max);
    	}
    	return 0;
    } 
    

    方法②:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    char a[5005],b[5005];
    short dp[5005][5005];
    int l;
    int main(){
    	while(scanf("%d",&l)!=EOF){
    		memset(a,0,sizeof(a));
    		a[0]='^';
    		scanf("%s",a+1);
    		strcpy(b,a);
    		memset(dp,0,sizeof(dp));
    		reverse(b+1,b+l+1);
    		for(int i=1;i<=l;i++)
    		for(int j=1;j<=l;j++){
    			if(a[i]==b[j])dp[i][j]=dp[i-1][j-1]+1;
    			else
    			dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
    		}
    		printf("%d
    ",l-dp[l][l]);
    	}
    	return 0;
    } 
    
  • 相关阅读:
    毕业进度10
    毕业进度9
    毕业进度8
    毕业设计7
    毕业设计6
    java算法每日一练2021/1/26
    java算法每日一练2021/1/23
    java算法每日一练2021/1/21
    java算法每日一练2021/1/20
    java算法每日一练2021-01-18
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/6973358.html
Copyright © 2011-2022 走看看