题目大意

两个字符串strA和strB(长度最大为2100),他们中按照顺序有一些公共的子串,且公共子串的长度大于等于3,否则不认为是合法的,比如 abcdef 和 abcxcdef, 按照顺序有合法公共子串abc def 或者 cdef。 
    按照顺序取出一些公共子串,有不同的取法,求这些取法中公共子串长度之和的最大值。

题目分析

字符串长度最大为2100,因此直接枚举搜索会超时,考虑使用动态规划,且复杂度要降到 O(n^3) 甚至 O(n^2). 用状态 dp[i][j][0] 表示strA 前i个字符和strB 前j个字符中满足合法条件的公共子串的长度之和; dp[i][j][1] 表示strA 前i个字符和strB 前j个字符的公共后缀的长度。

状态 dp[i][j][1] 很好找到状态转移方程,而对于 dp[i][j][0]: 
(1)如果 strA[i-1] == strB[j-1],可以根据 dp[i][j][1] 来看,如果 dp[i][j][1] 大于等于3,即为len,则dp[i][j][0]可以根据 dp[i-k][j-k][0]来进行更新(其中k >= 3, k <= len)。因为 在选择最后一个子串的时候,可以选择长度为3,4...len。

(2)如果 strA[i-1] != strB[j-1],则 dp[i][j][0] = max{dp[i][j-1][0], dp[i-1][j][0]}

实现

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<stack>
#include<vector>
#include<unordered_set>
#include<unordered_map>
using namespace std; int dp[2200][2200][2];
//dp[i][j][0] 表示 strA 前i个字符和strB前j个字符中满足条件的公共子串的长度之和
//dp[i][j][1] 表示 strA 前i个字符和strB前j个字符的公共后缀的长度
char strA[2200];
char strB[2200];
int max(int a, int b){
return a > b ? a : b;
}
int main(){
scanf("%s", strA);
scanf("%s", strB);
int m = strlen(strA);
int n = strlen(strB);
memset(dp, 0, sizeof(dp)); for (int i = 1; i <= m; i++){
for (int j = 1; j <= n; j++){
dp[i][j][0] = max(dp[i - 1][j][0], dp[i][j - 1][0]);
if (strA[i - 1] == strB[j - 1]){
dp[i][j][1] = dp[i - 1][j - 1][1] + 1;
if (dp[i][j][1] >= 3){
dp[i][j][0] = max(dp[i][j][0], dp[i - 3][j - 3][0] + 3);
dp[i][j][0] = max(dp[i][j][0], dp[i - dp[i][j][1]][j - dp[i][j][1]][0] + dp[i][j][1]);
}
/*
if (dp[i][j][1] >= 3){ //当以 strA以i结尾,strB 以j结尾的后缀长度dp[i][j][1]大于等于3,则需要进行状态更新
//不能直接 dp[i][j][0] = max(dp[i][j][0], dp[i - dp[i][j][1]][j - dp[i][j][1]][0] + dp[i][j][1]);
//这样有可能不是最优解,例如 abcdef, abcxcdef. 最后的 dp[i][j][1] = 4, 如果计算dp[6][7][0]的时候使用dp[i][j][1] = 4
//进行状态转移,那么只计算 dp[6][7][0] = max(dp[6][7][0], dp[2][3][0] + 4) 而dp[2][3][0] = 0,
//而此时的最优结果为 dp[3][4][0] + 3 (dp[i][j][1] 中只取后面的一部分就够了)
for (int k = 3; k <= dp[i][j][1]; k ++)
dp[i][j][0] = max(dp[i][j][0], dp[i - k][j - k][0] + k);
}
*/
}
}
}
printf("%d\n", dp[m][n][0]);
return 0;
}

hiho_1059_string matching content length的更多相关文章

  1. String Matching Content Length

    hihocoder #1059 :String Matching Content Length 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 We define the ...

  2. Hihocoder 1059 String Matching Content Length

    预处理下连续相等的字符个数其实主要是看是否满3个 后面递推的时候特判下+1上次递推[i-1,j-1]不是来自[i-2,j-1]也不是来自[i-1,j-2]其实就是只来自[i-4,j-4]+3,和[i- ...

  3. WCF常见异常-The maximum string content length quota (8192) has been exceeded while reading XML data

    异常信息:The maximum string content length quota (8192) has been exceeded while reading XML data 问题:调用第三 ...

  4. The maximum string content length quota (8192) has been exceeded while reading XML data

    原文:The maximum string content length quota (8192) has been exceeded while reading XML data 问题场景:在我们W ...

  5. 定时器setInterval, innerText获取文本, charAt()获取单个字符串, substring(1, content.length)获取范围内的字符串, 实现字符串的滚动效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. ics httpDELETE 时增加 content,length 特别需求

    unit: OverbyteIcsHttpProt.pasprocedure THttpCli.SendRequest(const Method, Version: String); var Head ...

  7. 调用WebServiceWebService提示The maximum string content length quota (8192) has been exceeded while reading XML data的解决办法

    在web.config中,bindings节点下,对应的服务名称中,原本可能是自动折叠的“/>”,需要改成手动折叠的</binding>,然后在中间加上<readerQuota ...

  8. nutch-1.7-二次开发-Content中增加编码

    1 识别nutch-1.7的编码,完成 以前1.2是在 org.apache.nutch.parse.html.HtmlParser EncodingDetector detector = new E ...

  9. JVM 平台上的各种语言的开发指南

    JVM 平台上的各种语言的开发指南 为什么我们需要如此多的JVM语言? 在2013年你可以有50中JVM语言的选择来用于你的下一个项目.尽管你可以说出一大打的名字,你会准备为你的下一个项目选择一种新的 ...

随机推荐

  1. Conditional - 编译屏蔽特性

    public class Test : MonoBehaviour { void Start() { Func(); } [System.Diagnostics.Conditional("U ...

  2. SQL生成规则数

    --------------------------开始----------------------------开始值DECLARE @start INT = 1--结束值DECLARE @end I ...

  3. LYK 与实验室

    LYK 与实验室(lab)Time Limit:5000ms Memory Limit:64MB[题目描述] LYK 在一幢大楼里,这幢大楼共有 n 层,LYK 初始时在第 a 层上.这幢大楼有一个秘 ...

  4. 多条件查询(php+mysql) 租房子例子

    <body> <?php //多条件 $tiaojian2= " 2=2 "; $attr2 = ""; //判断区域 if(!empty($ ...

  5. C#For循环

    for循环基本格式 for(初始条件;循环条件;状态改变) { 循环体 } 1.小明单位发了100元的购物卡,小明到超市买三类洗化用品,洗发水(15元),香皂(2元),牙刷(5元).要把100元整好花 ...

  6. Cheatsheet: 2013 06.23 ~ 06.30, Farewell GoogleReader(2008.07.20~2013.06.30)

    Mobile Resources for Mac and iOS Developers- Introduction to Objective-C Modules Other 10 Principles ...

  7. PHP中的替代语法(冒号、endif、endwhile、endfor)

    我们经常在wordpress一类博客程序的模板里面看到很多奇怪的PHP语法,比如: <?php if(empty($GET_['a'])): ?> <font color=" ...

  8. [POJ3667]Hotel(线段树,区间合并)

    题目链接:http://poj.org/problem?id=3667 题意:有一个hotel有n间房子,现在有2种操作: 1 a,check in,表示入住.需要a间连续的房子.返回尽量靠左的房间编 ...

  9. struts2--表单标签

    struts2的表单标签可分为两类:form标签本身和包装HTML表单元素的其他标签.form标签本身的行为不同于它内部的元素. struts2表单标签包括: form.textfield.passw ...

  10. WebSphere MQ 入门指南

    WebSphere MQ 入门指南这是一篇入门指南.我们从最基本的概念说起: 基础概念 对于MQ,我们需要知道4个名词:队列管理器.队列.消息.通道:对于编程设计人员,通常更关心消息和队列,对于维护管 ...