【动态规划】 回文词

本文深入探讨了如何运用动态规划算法来检测和构建回文词。通过实例解析,详细阐述了状态转移方程的建立过程,帮助读者理解动态规划在解决回文问题上的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
From Zossin
回文词  国际信息学奥林匹克竞赛 (IOI) 竞赛原题
 
   
  
  描述 Description 
   回文词是一种对称的字符串——也就是说,一个回文词,从左到右读和从右到左读得到的结果是一样的。任意给定一个字符串,通过插入若干字符,都可以变成一个回文词。你的任务是写一个程序,求出将给定字符串变成回文词所需插入的最少字符数。
  比如字符串“Ab3bd”,在插入两个字符后可以变成一个回文词(“dAb3bAd”或“Adb3bdA”)。然而,插入两个以下的字符无法使它变成一个回文词。
   
   
 输入格式 Input Format 
   第一行包含一个整数N,表示给定字符串的长度,3<=N<=5000
  第二行是一个长度为N的字符串,字符串由大小写字母和数字构成。
   
   
  输出格式 Output Format 
 一个整数,表示需要插入的最少字符数。
   
   
  样例输入 Sample Input 
 
   
   
  样例输出 Sample Output 
 
   
   
  时间限制 Time Limitation 
 各个测试点1s
   

 

 

 

 

来源 Source

 

 

IOI 2000
by Zossin

 

 

用f[i,j]来表示将区间[i,j]里面的词变成回文串所需要的最小变化个数

显然此题可以由区间扩展而得来。

边界   f[i,i+1]:=0              //a[i]=a[i+1]

          f[i,i]:=0;

 

转移方程  f[i,j]:=      f[i+1,j-1]     //a[i]=a[j]

                           min(   f[i+1,j],   f[i,j-1]  )+1 

最后输出 f[1,n]

 

由于转移的顺序难以确定,我又写了个记忆化搜索。

var n,i,j:longint;
    a:array[1..5000]of char;
    f:array[0..5000,0..5000]of longint;

function min(a,b:longint):longint;
begin
  if a>b then exit(b) else exit(a);
end;


function dp(i,j:longint):longint;
begin
    if f[i,j]<>-1 then exit(f[i,j]);
    if (a[i]=a[j])and(i+1=j) then
    begin
        f[i,j]:=0;
        exit(f[i,j]);
    end;
    if a[i]=a[j] then
    begin
       f[i,j]:=dp(i+1,j-1);
       exit(f[i,j]);
    end;
    
    if a[i]<>a[j] then
    begin
      f[i,j]:=min(dp(i,j-1),dp(i+1,j))+1;
      exit(f[i,j]);
    end;
end;

begin
    fillchar(f,sizeof(f),$7f);
    readln(n);
    for i:=0 to n-1 do for j:=i to n do f[i,j]:=-1;
    for i:=1 to n do read(a[i]);
    for i:=1 to n do f[i,i]:=0;
    writeln(dp(1,n));
    readln;readln;
end.


 

      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值