【UVA1371】Period (二分+DP)

题意:

  给出两个字符串A,B将B分解成若干个子字符串,然后每个子字符串都要经过编辑变成字符串A,所有子串中编辑最多的次数即为当前状态下的最大编辑次数,要求求最小的最大编辑次数。

  编辑操作包括修改、删除和插入。(|A|<=5000,|B|<=50)

 

分析:

  因为A的长度较大,直接算出A每个区间对应B的编辑次数的方法是不可取的。因为是求最大值最小化,可以想到二分答案然后判断。

  判断的时候用DP,dp[i][j]表示到1~i的字符串匹配到j的最大编辑次数。当dp[i][m]<=mid时(mid为二分出来的当前答案),就可以将dp[i][0] 置0,表示做为起点(因为此时可以在i后面分段)。

  打代码的时候出现了一个问题,当我dp[i][m]<=mid时,我把dp[i][0] 置0的同时,还把dp[i]的其他值全部置成INF,这样做是有问题的。比如,x=abcdabcabb,y=abc,当mid=1时,前面两个字符ab的编辑长度刚好为一,此时我直接把ab分成一段了,这样导致我把第三个字符c扔在一边。其实把abc一起放成一段更好。问题就出在我把dp[i][0] 置0的同时还把dp[i]的其他值全部置成INF。这样做相当于默认我把i前面的分成一段,但事实上或许再加一个字符编辑距离仍然不超过mid,这样可能会使后面的答案更优而我却没有找到最优解,于是就产生判断错误。所以只需把dp[i][0] 置0即可,这样子就表示我们可以把i前面的字符分成一段,当然也可以再加一些字符再分成一段。

 

代码如下:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<iostream>
 6 using namespace std;
 7 #define Maxn 5010
 8 #define Maxm 60
 9 
10 char a[Maxn],b[Maxm];
11 int n,m;
12 
13 int f[Maxn][Maxm];
14 
15 int mymin(int x,int y) {return x<y?x:y;}
16 
17 bool dp(int x)
18 {
19     memset(f,63,sizeof(f));
20     for(int i=0;i<=m;i++) f[0][i]=i;
21     for(int i=1;i<=n;i++)
22     {
23         for(int j=1;j<=m;j++)
24         {
25             if(a[i]==b[j]) f[i][j]=mymin(f[i][j],f[i-1][j-1]);
26             else f[i][j]=mymin(f[i][j],f[i-1][j-1]+1);
27             f[i][j]=mymin(f[i][j],f[i-1][j]+1);
28             f[i][j]=mymin(f[i][j],f[i][j-1]+1);
29         }
30         if(f[i][m]<=x)
31         {
32             if(i==n) return 1;
33             f[i][0]=0;
34         }
35         if(i==n) return 0;
36     }
37 }
38 
39 void ffind()
40 {
41     scanf("%s%s",b+1,a+1);
42     n=strlen(a+1);m=strlen(b+1);
43     int l=0,r=n;
44     while(l<r)
45     {
46         int mid=(l+r)>>1;
47         if(dp(mid)) r=mid;
48         else l=mid+1;
49     }
50     printf("%d\n",l);
51 }
52 
53 int main()
54 {
55     int T;
56     scanf("%d",&T);
57     while(T--)
58     {
59         ffind();
60     }
61     return 0;
62 }
uva1371

2016-03-06 16:47:51

 

貌似已经看到很多题二分加DP了~

 

转载于:https://www.cnblogs.com/Konjakmoyu/p/5247860.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的影城管理系统,源码+数据库+论文答辩+毕业论文+视频演示 随着现在网络的快速发展,网上管理系统也逐渐快速发展起来,网上管理模式很快融入到了许多生活之中,随之就产生了“小徐影城管理系统”,这样就让小徐影城管理系统更加方便简单。 对于本小徐影城管理系统的设计来说,系统开发主要是采用java语言技术,在整个系统的设计中应用MySQL数据库来完成数据存储,具体根据小徐影城管理系统的现状来进行开发的,具体根据现实的需求来实现小徐影城管理系统网络化的管理,各类信息有序地进行存储,进入小徐影城管理系统页面之后,方可开始操作主控界面,主要功能包括管理员:首页、个人中心、用户管理、电影类型管理、放映厅管理、电影信息管理、购票统计管理、系统管理、订单管理,用户前台;首页、电影信息、电影资讯、个人中心、后台管理、在线客服等功能。 本论文主要讲述了小徐影城管理系统开发背景,该系统它主要是对需求分析和功能需求做了介绍,并且对系统做了详细的测试和总结。具体从业务流程、数据库设计和系统结构等多方面的问题。望能利用先进的计算机技术和网络技术来改变目前的小徐影城管理系统状况,提高管理效率。 关键词:小徐影城管理系统;Spring Boot框架,MySQL数据库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值