• [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;
    } 
    
  • 相关阅读:
    hdoj 6023 Automatic Judge
    hdoj 1170 Balloon Comes!
    初识vim操作和配置
    POJ 1611 The Suspects (并查集)
    HDU 1232 畅通工程 (并查集)
    计蒜客--两数之和
    计蒜客--爬楼梯 (动态规划)
    计蒜客--单独的数字 (位运算)
    计蒜客--最后一个单词的长度
    计蒜客-- 奇怪的国家 (位运算)
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/6973358.html
Copyright © 2020-2023  润新知