区间dp-添加最少字符成为回文串

水题吧,记忆化搜索即可


回文字符串

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 4
描述
所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如"aba"。当然,我们给你的问题不会再简单到判断一个字符串是不是回文字符串。现在要求你,给你一个字符串,可在任意位置添加字符,最少再添加几个字符,可以使这个字符串成为回文字符串。
输入
第一行给出整数N(0<N<100)
接下来的N行,每行一个字符串,每个字符串长度不超过1000.
输出
每行输出所需添加的最少字符数
样例输入
1
Ab3bd
样例输出
2
来源
IOI 2000

/****************************************
* author:crazy_石头
* pro:回文字符串-区间dp 
* date:2014/04/16
* algorithm: dp 
* 思路: 区间dp固定模式:
*  考虑i~j区间的字符串;
* 1.是一个字符的话回文,添加字符数量为0;
* 2.是两个字符并且相等的话也是回文的,添加字符数量为0;
* 3.一般情况,就是考虑第i个字符,如果第j个字符处的字符与它不相等的话,
*那么把第i个字符和后面的串隔离开,给第i个字符单独添加一个字符,即:
* dp[i][j]=dp[i+1][j]+1;(dp[i+1][j]是隔离开的串,加的1就是给dii个字符加的
* 所以dp[i][j]=std::min(dfs(i+1,j)+1,dfs(i,j-1)+1);看懂了吧? 
*****************************************/ 
#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
         #include 
        
          #include 
         
           #include 
          
            #include 
           
             using namespace std; #define INF INT_MAX #define eps 1e-8 #define A system("pause") #define rep(i,h,n) for(int i=(h);i<=(n);i++) #define ms(a,b) memset((a),(b),sizeof(a)) #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define mod 1e9+7 #define LL long long const int maxn=1000+5; char ch[maxn]; int d[maxn][maxn]; inline int dfs(int i,int j) { if(~d[i][j]) return d[i][j]; if(i==j) return d[i][j]=0; if(ch[i]==ch[j]&&i+1==j)//是回文双字符,无需添加字符 return d[i][j]=0; if(ch[i]==ch[j]) return d[i][j]=dfs(i+1,j-1);//匹配的话不管最外层括号,相当于往近了一层; d[i][j]=std::min(dfs(i+1,j)+1,dfs(i,j-1)+1); return d[i][j]; } int main() { int n; scanf("%d",&n); while(n--) { scanf("%s",ch); ms(d,-1); int len=strlen(ch); int ans=dfs(0,len-1); printf("%d\n",ans); } return 0; } 
            
           
          
         
       
      
      
     
     
    
    
   
   

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值