题目求两个字符串s1,s2不同的LCS个数。

经典的求LCS的DP是这样的:

  • LCS[i][j]表示s1[0...i]和s2[0...j]的LCS
  • LCS[i][j]从LCS[i-1][j-1]+1(s1[i]==s2[j])或max(LCS[i-1][j],LCS[i][j-1])(s1[i]!=s2[j])转移来

计数的话也跟着转移,用dp[i][j]计数。不过搞不出。。看了别人的解法才恍然大悟,要减去多算的部分,即s1[i]!=s2[j]且LCS[i-1][j]等于LCS[i][j-1]时这种情况的转移,如果只是dp[i][j]=dp[i-1][j]+dp[i][j-1]可能会有重复算的部分:

  • LCS[i-1][j]等于LCS[i][j-1],且LCS[i-1][j-1]不与它们相等,那样s1[0...i-1]和s2[0...j]所有的LCS必定以s2[j]为结尾,s1[0...i]和s2[0...j-1]同理,所以s1[0...i-1]和s2[0...j]所有的LCS和s1[0...i]和s2[0...j-1]的所有LCS没有相交部分,dp[i][j]=dp[i-1][j]+dp[i][j-1];
  • 而如果LCS[i-1][j-1]等于它们的情况,就说明存在不以s1[i]和s2[j]结尾的LCS,多算了一次s1[0...i-1]和s2[0...j-1]的所有LCS的部分,这时dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]。

另外注意负数取模。

 #include<cstdio>
#include<cstring>
using namespace std;
int lcs[][],d[][];
int main(){
char s1[],s2[];
int t;
scanf("%d",&t);
for(int cse=; cse<=t; ++cse){
scanf("%s%s",s1+,s2+);
int l1=strlen(s1+),l2=strlen(s2+);
for(int i=; i<=l1; ++i) d[i][]=;
for(int i=; i<=l2; ++i) d[][i]=;
for(int i=; i<=l1; ++i){
for(int j=; j<=l2; ++j){
if(s1[i]==s2[j]){
lcs[i][j]=lcs[i-][j-]+;
d[i][j]=d[i-][j-];
}else if(lcs[i-][j]==lcs[i][j-]){
lcs[i][j]=lcs[i-][j];
d[i][j]=(d[i-][j]+d[i][j-])%;
if(lcs[i-][j-]==lcs[i-][j]) d[i][j]=((d[i][j]-d[i-][j-])%+)%;
}else if(lcs[i-][j]>lcs[i][j-]){
lcs[i][j]=lcs[i-][j];
d[i][j]=d[i-][j];
}else{
lcs[i][j]=lcs[i][j-];
d[i][j]=d[i][j-];
}
}
}
printf("Case %d: %d\n",cse,d[l1][l2]);
}
return ;
}

LightOJ1157 LCS Revisited(DP)的更多相关文章

  1. LightOJ 1033 Generating Palindromes(dp)

    LightOJ 1033  Generating Palindromes(dp) 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid= ...

  2. lightOJ 1047 Neighbor House (DP)

    lightOJ 1047   Neighbor House (DP) 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87730# ...

  3. UVA11125 - Arrange Some Marbles(dp)

    UVA11125 - Arrange Some Marbles(dp) option=com_onlinejudge&Itemid=8&category=24&page=sho ...

  4. 【POJ 3071】 Football(DP)

    [POJ 3071] Football(DP) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4350   Accepted ...

  5. 初探动态规划(DP)

    学习qzz的命名,来写一篇关于动态规划(dp)的入门博客. 动态规划应该算是一个入门oier的坑,动态规划的抽象即神奇之处,让很多萌新 萌比. 写这篇博客的目标,就是想要用一些容易理解的方式,讲解入门 ...

  6. Tour(dp)

    Tour(dp) 给定平面上n(n<=1000)个点的坐标(按照x递增的顺序),各点x坐标不同,且均为正整数.请设计一条路线,从最左边的点出发,走到最右边的点后再返回,要求除了最左点和最右点之外 ...

  7. 2017百度之星资格赛 1003:度度熊与邪恶大魔王(DP)

    .navbar-nav > li.active > a { background-image: none; background-color: #058; } .navbar-invers ...

  8. Leetcode之动态规划(DP)专题-详解983. 最低票价(Minimum Cost For Tickets)

    Leetcode之动态规划(DP)专题-983. 最低票价(Minimum Cost For Tickets) 在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行.在接下来的一年里,你要旅行的 ...

  9. 最长公共子序列长度(dp)

    /// 求两个字符串的最大公共子序列长度,最长公共子序列则并不要求连续,但要求前后顺序(dp) #include <bits/stdc++.h> using namespace std; ...

随机推荐

  1. Mysql性能监控

    show processlist; show global variables like 'max_allowed_packet'; // QPS计算(每秒查询数)show global status ...

  2. magic-encoding

    (文章都是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) 今天页面跳转都出问题了,各种方法都试过了, log里说语法错误,问了pp,他说是汉字的原因...果 ...

  3. 深度学习入门教程UFLDL学习实验笔记一:稀疏自编码器

    UFLDL即(unsupervised feature learning & deep learning).这是斯坦福网站上的一篇经典教程.顾名思义,你将在这篇这篇文章中学习到无监督特征学习和 ...

  4. HM必修3

    高中数学必修三 笔记与拓展 算法初步 算法是按照一定规则解决固定问题,通过对输入的某种变换产生结果. 素性测试 检验一个数是否为素数. 试除法 一个数是素数的充分必要条件是它因数个数为二.显然1和它本 ...

  5. chrome断点续传功能

    刚好找到了一个临时的解决方法,chrome其实已经内部实现了断点续传功能,不过应该还没完善,所以要自己打开.方法:用chrome在地址栏输入chrome://flags用搜索找到resumption( ...

  6. 【Django】Django 文件下载最佳实践

    代码: from django.http import StreamingHttpResponse def big_file_download(request): # do something... ...

  7. Greedy:Protecting the Flowers(POJ 3262)

    保护花朵 题目大意:就是农夫有很多头牛在践踏花朵,这些牛每分钟破坏D朵花,农夫需要把这些牛一只一只运回去,这些牛各自离牛棚都有T的路程(有往返,而且往返的时候这只牛不会再破坏花),问怎么运才能使被践踏 ...

  8. poj 2739 Sum of Consecutive Prime Numbers 解题报告

    题目链接:http://poj.org/problem?id=2739 预处理出所有10001以内的素数,按照递增顺序存入数组prime[1...total].然后依次处理每个测试数据.采用双重循环计 ...

  9. mybatis配置文件xml中插入新数据

    初用mybatis,发现很好的一个操作数据库的框架,里面有一些小技巧,挺简单,很实用,记录一下: mybatis的插入语句: <insert id="insertAsset" ...

  10. MFC 颜色选择对话框、颜色按钮

    COLORREF color=RGB(0,255,0); unsigned char r=GetRValue(color); unsigned char g=GetGValue(color); uns ...