题目求两个字符串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. 理解Java中的接口

    一.为什么要使用接口 假如有一个需求:要求实现防盗门的功能.门有"开"和"关"的功能,锁有"上锁"和"开锁"的功能. 分 ...

  2. UIImage imageNamed和UIImage imageWithContentsOfFile区别

    UIImage imageNamed和 [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:imageNam ...

  3. search in 2d matrix and serach minimum in rotated array

    import java.io.*; import java.lang.reflect.Array; import java.util.Arrays; import java.util.Collecti ...

  4. Mathematica 中 Minimize函数无法找到全局最小值时的解决方法

    一直使用Minimize来找到指定约束下的函数的最小值,最近发现在一个非线性函数中使用Minimize无法提供一个"全局"最小值(使用Mathematica只是用来验证算法的,所以 ...

  5. Apache同时支持PHP和Python的配置方法

      一.http://www.oschina.net 网站中的一个问答内容: 原来把 WSGIScriptAlias / "D:/project/ddd/django.wsgi"  ...

  6. poj2253 最短路 floyd Frogger

    Frogger Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 28825   Accepted: 9359 Descript ...

  7. android menu showAsAction属性

    app中有一个菜单(menu),showAsAction主要是针对这个菜单的显示起作用的,它有三个可选项:always:总是显示在界面上 never:不显示在界面上,只让出现在右边的三个点中 ifRo ...

  8. 10 Python Optimization Tips and Issues

    转自: http://www.algorithm.co.il/blogs/computer-science/10-python-optimization-tips-and-issues/

  9. Xenomai

    http://blog.csdn.net/robertsong2004/article/details/43889249 嵌入式系统的开发,如果对实时性要求不高,就可以使用Linux自身的实时补丁实现 ...

  10. linux 多个文件中查找字符串

    2015年2月9日 14:36:38 # find <directory> -type f -name "*.c" | xargs grep "<str ...