字符串上的动态规划算法--------单字符串的情况
禁止字符串
考虑只由‘A’,’G’,’C’,’T’四种字符组成的DNA字符串。给定一个长度为 k的字符串 S。请计算长度恰好为 n且不包含S的字符串的个数。输出个数mod 10009后的结果。
首先,我们来考虑生成所有的满足条件的字符串这一直观的解法。字符串的个数可能高达4^n,这显然是行不通的。接下来,与其在生成字符串后再判断它是否包含 S,不如在穷竭搜索中每在末尾加一个字符,都确保其最后k个字符不等于 S。可以发现最后 k个字符之前的字符对以后的搜索都无影响。(符合无后向性,不懂可以看看我写的动态规划一般解法的文章)所以我们可以以剩余字符的个数和最后k-1个字符为状态进行动态规划。这样的状态数依然高达4^(k-1)。不过事实上可以将其中的许多状态看作是等价的,从而大大减少所需的状态数。首先我们以 S等于“ATCG”为例进行分析。动态规划的状态是字符的个数和最后的3个字符。
譬如说,我们可以将最后三个字符为“TTA”的状态和“CCA”的状态看作是等价的。这是因为‘A’是S的第一个字符,所以“TT”或“CC”这两个字符对以后是否出现S并无影响。同理可知,对于以‘A’结尾的状态,‘A’前面的字符是什么并不重要。由此可知,我们可以将“*A”(‘’代表任意一个字符)看作一个状态。
以‘T’结尾的状态又如何呢?’T’是‘S’的第二个字符。因此要使该字符对 S的出现有影响,其前面的字符必须是’A’,并且同之前分析的一样,在前面的字符是什么并无影响。所以可以将”**AT“看作一个状态。而如果‘T’前面的字符不是’A‘的话,那么这个’T‘也可以无视。
综合以上分析,我们知道最初的4^3种状态,可以归纳为以下4种
“A”,”*AT”,”ATC”,其他
也就是把所生成字符串的后缀和S的前缀相匹配的长度作为状态。所以,状态总数只有k个。
接下来,我们来考虑一个更为复杂的例子,令S等于“ATCATCG”。此时,有个地方需要稍微注意一下。简单地像前面一样处理的话,将得到“ATCATC”和“**ATC”这两个状态。如果我们对 “***ATC”的前3个字符不加任何限制的话,那么就发生了以“ATCATC”结尾的状态,同时属于这两个状态这一奇怪现象。不过,要解决这一问题也很容易。最初我们引入‘’时,是用于代替那些已知对以后是否出现是否出现S无影响的字符。对于“ATCATC”,如果下一个字符是‘G’的话,就得到了S,对S的出现是有影响的。所以“ATCATC”不应该属于“***ATC”。
将这个一般化就会发现,状态应该是所生成字符串的后缀和S的前缀相匹配的长度,只不过当有多种匹配时,应当选择最长的作为状态。
为了让动态规划算法部分更加高效,下面的程序预先处理出了从某个状态添加某个字符后的状态转移表,然后利用该完成动态规划。预处理部分的复杂度是O(k^3),动态规划的复杂度是O(kn)。
/*
禁止字符串
考虑只由'A','G','C','T'四种字符组成的 DNA字符串。给定一个长度为 k的字符串 S。
请计算长度恰好为 n且不包含 S的字符串的个数。输出个数 mod 10009后的结果
*/
#include<iostream>
#include<string.h>
#include<cstdio>
using namespace std;
const char *AGCT = "AGCT";
const int MOD = 10009;
const int MAX_K = 105;
const int MAX_N = 10005;//输入
int N,K;
string S;
int next[MAX_K][4];//添加某个字符串后转移到的状态
int dp[MAX_N + 1][MAX_K];void solve(){//预处理for(int i=0;i<K;i++){for(int j=0;j<4;j++){//在 S长度为 i的前缀后添加一个字符string s = S.substr(0,i) + AGCT[j];//反复删除第一个字符,直到成为 S的前缀while(S.substr(0,s.length()) != s){s = s.substr(1);} next[i][j] = s.length(); } } //动态规划边界的初值dp[0][0] = 1;for(int i=1;i<K;i++)dp[0][i] = 0;//动态规划for(int t=0;t<N;t++){for(int i=0;i<K;i++)dp[t+1][i] = 0;for(int i=0;i<K;i++){for(int j=0;j<4;j++){int ti = next[i][j];if(ti == K)continue;//不允许出现 Sdp[t+1][ti] = (dp[t+1][ti] + dp[t][i]) % MOD; } } } int ans = 0;for(int i=0;i<K;i++){ans = (ans + dp[N][i]) % MOD; } printf("%d\n",ans);
}
int main(){cin>>N>>K;cin>>S;solve(); return 0;
}
字符串上的动态规划算法--------单字符串的情况相关推荐
- 字符串上的动态规划算法--------多字符串的情况
DNA Repair 考虑只由'A','G','C','T'四种字符组成的 DNA字符串.给定一个原字符串 S,和 n个禁止模式字符串 p1,p2,..,pn.请修改字符串 S,使得其中不包含任何禁止 ...
- 【字符串】最长回文子串 ( 动态规划算法 ) ★
文章目录 一.回文串.子串.子序列 二.最长回文子串 1.动态规划算法 2.动态规划算法代码示例 一.回文串.子串.子序列 " 回文串 ( Palindrome ) " 是 正反都 ...
- 最长公共子序列算法 java_转【算法之动态规划(三)】动态规划算法之:最长公共子序列 最长公共子串(LCS)字符串相似度算法...
1.先科普下最长公共子序列 & 最长公共子串的区别: 找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的.而最长公共子序列则并不要求连续. 2.最长公共子串 其实这是一个序贯决策问题 ...
- c语言gga字符串校验和代码,一种新的Java智能卡上字节码校验算法.pdf
您所在位置:网站首页 > 海量文档  > 计算机 > Java 一种新的Java智能卡上字节码校验算法.pdf4页 本 ...
- 动态规划算法解最长公共子序列LCS问题
动态规划算法解LCS问题 作者 July 二零一零年十二月三十一日 本文参考:微软面试100题系列V0.1版第19.56题.算法导论.维基百科. 第一部分.什么是动态规划算法 ok,咱们先来了解下什么 ...
- 算法分析与设计-实验二 动态规划算法设计
文章目录 1. 数字三角问题 2.最长公共子序列问题 3.日常购物 4.台阶问题 一.实验目的: 掌握动态规划算法的基本思想及适用条件,掌握动态规划算法的设计步骤和具体实现. 二.实验所用仪器及环境 ...
- java动态规划算阶乘_动态规划算法
上世纪40年代,RichardBellman最早使用动态规划这一概念表述通过遍历寻找最优决策解问题的求解过程.1953年,RichardBellman将动态规划赋予现代意义,该领域被IEEE纳入系统分 ...
- 动态规划算法入门---java版
转载:http://blog.csdn.net/p10010/article/details/50196211 动态规划算法(后附常见动态规划为题及Java代码实现) 一.基本概念 动态规划过程是:每 ...
- 经典算法题:字典树、并查集、单调栈、二分、带标记函数dp、树、全排列、字符串问题等常用算法
0. Tips 1. 位运算 如何枚举一个二进制状态数字k的子集, 方法就是针对中的二进制为1的位开始进行减法,判断数字k的二进制子集, 像枚举(2^k-1) ~ 0一样枚举其子集: int sub ...
最新文章
- python和mt4的区别_MT4和MT5有什么区别?
- Django 模型 —— 字段类型
- 在nodejs环境里使用浏览器环境下的document对象
- python语言及其应用电子版翁正秋_Python语言及其应用pdf
- java ui自动化测试脚本,如何用Airtest编写UI自动化脚本(示例代码)
- linux系统ip占用,IP地址被占用的问题,折腾我好几天了 (已解决)
- Hadoop 安装教程
- python酒店评论分析_酒店评论的情感分析
- 解决网站iframe挂马方法
- 超级大反派降临:当黑客可以摧毁人造卫星
- input file类型单个文件上传formData
- 计算机的专业课听不懂怎么办,为什么大学计算机课难以听懂?
- A	 ConneR and the A.R.C. Markland-N
- Web应用程序项目某某某已配置为使用IIS。无法访问IIS元数据库。您没有足够的特权访问计算机上的IIS网站
- HTML5~用户注册页面的设计与实现
- nginx openresty DNS resolver配置实例,通过配置resolver解决proxy_pass中使用变量参数,高性能负载均衡 NGINX Plus 中 RESTful API
- 搭建云服务器简单流程【华为云服务器】
- elisa数据处理过程图解_(完整版)ELISA原理和分类(附图解)
- 从1到100怎么做?小红书KOL五大阶段运营增长策略
- 【语音控制ROS】PocketPhinx语音包的使用<三>
热门文章
- api-ms-win-crt-runtime-|1-1-0.dll插件丢失(64位)
- qrobot开发总结之android手势识别
- JAVA 方法的练习
- Python - 七种武器之NumPy
- java项目2个数据源_springboot项目配置两个数据源的方法
- java http请求插件_Web测试调试插件RESTClient和HttpRequester
- 安装 pytorch-geometric
- GSMA公布2018“与CTIA合作的GSMA世界移动大会-美洲”的首批主题演讲嘉宾名单
- English trip EM2-PE 3B Teacher:Corrine Pros Cons
- 如何快速恢复删除的文件?数据还原方法分享