【总括】区间DP

题目一:USACO 2007 Open 最近回文

题目描述:

给出一个由前N (1 ≤ N ≤ 26)个小写字母组成的字串,长度为M (1 ≤ M ≤ 2,000) ,可以在任意位置插入或者删除字符,给出每种字母插入删除的代价。
求把字串修改成回文串的最小总代价。

样例输入:

3 4
abcb
a 1000 1100
b 350 700
c 200 800

样例输出:

900



思路:逼近法

增加该字母与删去该字母的效果是一样的,开一个cost数组取两者间的最小值表示修改该字母。

状态&状态转移方程:

f[i][j]表示将第i位到第j位的子串改为回文串的代价。

             f[i+1][j-1];  (str[i]==str[j])

f[i][j]=   min(f[i+1][j]+cost[i]  ,  f[i][j-1]+cost[j]);   (str[i]!=str[j])//因为删除的cost一定是正值所以当str[i]==str[j]的时候就不考虑删改i或j了。

                    删改左边的字符      删改右边的字符




题目二:UVa1626 括号序列

题目描述:

定义如下正则括号序列:
1.空序列是正则括号序列。
2.如果S是正则括号序列,那么(S)和[S]也是正则括号序列。
3.如果A和B都是正则括号序列,那么AB也是正则括号序列。
输入一个长度为n的,仅由(、)、[、]构成的序列,添加尽量少的括号,得到一个正则括号序列。输入串长度不超过100。

样例输入:

1

([(]

样例输入:

()[()]



思路:枚举断开点

状态&状态转移方程:

f[i][j]表示从第i个括号到第j个括号要配成正则括号序列最少额外需要的括号数。

          f[i+1][j-1]   (str[i]与str[j]可以配对)

f[i][j]=min(f[i][k]+f[k+1][j])   (注意这里没有str[i]与str[j]必须不能配对的限制,原因是str[i]与str[j]可能是两个不同的正则括号序列【条件3】,如"[][]")


输入解直接用s[i][j]保存f[i][j]的最优决策点k,dfs一遍即可。


注:该题之所以不能用逼近法(与题1的区别)就是因为存在多个正则括号序列,如果去掉法则3就和题1没什么区别了。



题目三:POJ1229 模糊匹配

题目描述:

给定两个模糊域名串s和t,每个串用圆点分成若干个部分(part),由英文字母和通配符组成。3种通配符的含义分别是:
*:匹配一个或多个部分;
?:匹配至少一个至多三个部分;
!:匹配至少三个部分。
通配符单独被分隔成一个部分。
问两个模糊域名串是否能够匹配。匹配是指至少能构造一个域名能匹配两个模糊串。

例如www.xyz.edu能匹配www.?.edu和?.edu

样例输入:

2
www.?.edu
?.edu
*.edu
yahoo.com

样例输出:

YES
NO


思路:LCS模型(两个字符串)

通配符的一陪有限个或有限个配任意的限制过于繁琐,变为一配一或者一配任意个就可以随意使用LCS模型了。

定义通配符如下:

@:匹配一个部分

#:匹配一个部分或啥都不匹配

$:匹配一个部分或多个部分

改造原有的通配符如下:

*$

!@@$

?@##


如此一来,状态&状态转移方程:

f[i][j](bool)表示str1前i位与str2前j位是否能匹配。

边界条件:f[0][0]=1;


f[i][j]=f[i][j] || f[i-1][j-1]    (str1[i]=='@')

f[i][j]=f[i][j] || f[i-1][j-1] || f[i-1][j]  (str1[i]=='#')      ->考虑str1的当前状态

f[i][j]=f[i][j] || f[i-1][j-1] || f[i][j-1]  (str1[i]=='$')


f[i][j]=f[i][j] || f[i-1][j-1]    (str2[i]=='@')

f[i][j]=f[i][j] || f[i-1][j-1] || f[i][j-1]  (str2[i]=='#')      ->考虑str2的当前状态(与str1相反)

f[i][j]=f[i][j] || f[i-1][j-1] || f[i-1][j]  (str2[i]=='$')




题目四:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值