#include<stdio.h>
#include<stdlib.h>
#include<iostream>//在P203页的表,i表示序列的起始位置,j表示序列的结束位置, L表示碱基对的最大值
// 比如说L[1][5] 对应的就是序列的第1个字母到第5个字母的序列,即CAUGA的最大碱基对
// 那么说L[0][14] 对应的序列是  ACAUGAUGGCCAUGU的最大碱基对,就是本问题的解 // 递推公式
// 在P201页中,如果序列中第j个字母,与前面i到j-4个字母都不匹配,那么L(i,j) = L(i,j-1)
//    如果序列中第j个字母与第t个字母匹配,其中i<t<j-4,那么L(i,j) = max{1+L(i,t-1)+L(t+1,j)}// 在P203页中的  左下角空白的部分都为0
//  递归表是沿着斜线进行填写的, 顺序为[0,5],[1,6],[2,7],[3,8],[4,9]。。。
//   ↘↘↘↘// 碱基对序列是从st[0,n-1] 往前倒推得到的。  // 其中用数组st记录其中的关键点,用来得到最大碱基对的结果 using namespace std;
// 碱基符号B, 符号个数n
// 最大碱基对个数,碱基对集合 s[][]
int basepair_match(char B[], int s[][2], int n){int i,j,t,k,sp,len,len1,temp;int stack[n/2][2]; //栈是在寻找碱基对组合的使用使用的 int L[n][n]; //L用来存放碱基对的长度 int st[n][n];// 用来记录关键点,即这个已经匹配,方便查找碱基对 //非关键点时,就是-1 , 关键点时,记录与之匹配碱基的下标 //初始化dp表,L中都赋值为0,st中都赋值为-1 for(i=0;i<n;i++)for(j=0;j<n;j++){//初始化 L[i][j] = 0;st[i][j] = -1;} //填写dp表  for(k=5;k<=n-1;k++){for(i=0;i<n-k;i++){j = i+k; //dp是斜着填的, 即i和j之前是隔着一个常数的  len=0;//len存储本次循环的最大值  temp=i;//temp存储最大值对应的下标 for(t=i; t<j-4; t++ ){//匹配到对应的碱基 A-U 或者 G-C if((B[t]=='A')&&(B[j]=='U') ||(B[t]=='U')&&(B[j]=='A')||(B[t]=='C')&&(B[j]=='G')||(B[t]=='G')&&(B[j]=='C')){if(i==t) len1 = 1 +L[i+1][j-1];//i==t 表示跟最后一个进行匹配 else len1 = 1 + L[i][t-1] + L[t+1][j-1]; // 在之前的找到一个匹配的 //比如当前值比最大值len大,就替换 if(len < len1){ len = len1; temp = t;}     }  }//碱基配对数没有前面的多,就用前面的值 if(L[i][j-1] >= len){L[i][j] = L[i][j-1];}else{//否则就进行更新 L[i][j] = len;st[i][j] = temp; //st也进行更新,用来记录关键点 } }}        //存储对应的碱基对 ,最大碱基对的组合sp = 0; //栈顶指针 k=0;stack[0][0] = 0;  stack[0][1] = n-1;while(sp>=0){//取出栈顶数据 i = stack[sp][0];j = stack[sp][1];sp = sp-1;// 栈顶指针减1 while(L[i][j]>0){if(st[i][j]==-1)j = j-1;//向前移动 else{s[k][0] = st[i][j];s[k++][1] = j;//序列被分割为两个子序列 if(st[i][j]-1-i>4){ //第一个子序列压入栈中 sp = sp+1;stack[sp][0] = i;stack[sp][1] = st[i][j] -1;}//第二个子序列的起点和终点,继续搜索 i = st[i][j] + 1;j = j -1;}}}   //打印st printf("\n"); printf("打印st表\n");printf("%3c",' ');for(int i=0;i<n;i++)printf("%3c",B[i]);printf("\n");printf("%3c",' ');for(int i=0;i<n;i++)printf("%3d",i);printf("\n");for(int i=0;i<n;i++){printf("%3d",i);for(int j=0; j<n;j++)printf("%3d",st[i][j]);printf("\n");} //打印L表printf("打印L表\n");printf("%3c",' ');for(int i=0;i<n;i++)printf("%3c",B[i]);printf("\n");printf("%3c",' ');for(int i=0;i<n;i++)printf("%3d",i);printf("\n");for(int i=0;i<n-5 ;i++){printf("%3d",i);for(int j=0; j<n;j++)printf("%3d",L[i][j]);printf("\n");}  return L[0][n-1];
} int main(){char B[]= "ACAUGAUGGCCAUGU";
//  char B[] = "UGUACCGGUAGUACACCC";int s[100][2];int len;for(len=0; B[len]!='\0';len++); //计算字符串B的长度 int max = basepair_match(B,s,len);printf("最大碱基配对数为%d\n",max);for(int i=0;i<max;i++)printf("%d-%d\n",s[i][0],s[i][1]);return 0;
}

算法-动态规划-RNA最大碱基对匹配问题C语言求解相关推荐

  1. 算法设计与分析男女匹配问题C语言,C语言解决新郎和新娘配对问题代码解析

    问题描述 有3对情侣结婚,假设2个新郎为A.B.C,3个新娘为X.Y.Z,有参加婚礼的人搞不清谁和谁结婚,所以去询问了这6位新人中的3位,得到的回答如下:新郎A说他要和新娘X结婚:新娘X说她的未婚夫是 ...

  2. 五大经典算法-动态规划 及其算法应用

    前言 整篇文章分析整个动态规划算法,什么是动态规划,及动态规划算法在字符串匹配中使用.分治法的差别点.动态规划优点: 概念 什么叫做动态规划(dynamic programming),它是运筹学的一个 ...

  3. 算法-动态规划算法总结

    1 基础问题 // 509. 斐波那契数 // 斐波那契数,通常用 F(n) 表示,形成的序列称为 斐波那契数列 .该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和.// dp[i]的 ...

  4. Dijkstra 贪心算法 动态规划

    我认为 Dijkstra算法 的本质是 广度优先搜索, 而此处的广度是定义在路程的cost之上的. (就好比从圆心处向外扩散一个圆环,首次碰到的就是最近) 动态规划泛指,重叠子问题与原问题的推算关系( ...

  5. 计算机算法的发展动态,计算机算法动态规划讲解.ppt

    计算机算法动态规划讲解 * 0-1背包问题 设所给0-1背包问题的子问题 的最优值为m(i,j),即m(i,j)是背包容量为j,可选择物品为i,i+1,-,n时0-1背包问题的最优值.由0-1背包问题 ...

  6. 【数学与算法】二部图、匈牙利匹配、稳定婚配

    二部图系列视频 关于匈牙利匹配可以联系下面两篇博客更容易理解和补盲: 带你入门多目标跟踪(三)匈牙利算法&KM算法 趣写算法系列之–匈牙利算法 14.1 二部图 广度优先搜索 广度优先,可以使 ...

  7. 漫画说算法--动态规划算法三(绝对通俗易懂,非常棒)

    在前两集漫画中,我们通过一个算法问题的完整解题过程,讲述了动态规划的基本概念和思想.没看过前两集的朋友可以点击下面的链接: 漫画说算法–动态规划算法一(绝对通俗易懂,非常棒) 漫画说算法–动态规划算法 ...

  8. ReviewForJob——算法设计技巧(贪婪算法+分治算法+动态规划)

    [0]README 1)本文旨在介绍算法设计技巧包括 贪婪算法.分治算法.动态规划 以及相关的荔枝等: [1]贪婪算法 1)intro: 贪婪算法是分阶段进行的,在每个阶段,可以认为所做的决定是最好的 ...

  9. 矩阵相乘的strassen算法_矩阵乘法的Strassen算法+动态规划算法(矩阵链相乘和硬币问题)...

    矩阵乘法的Strassen 这个算法就是在矩阵乘法中采用分治法,能够有效的提高算法的效率. 先来看看咱们在高等代数中学的普通矩阵的乘法 两个矩阵相乘 上边这种普通求解方法的复杂度为: O(n3) 也称 ...

最新文章

  1. .NET 框架中的 WMI 命名空间
  2. Excel 数据有效性,怎么提示指定的命名区域不存在?
  3. Android Animation学习(六) View Animation介绍
  4. revit如何根据坐标进行画线_在工程设计中如何根据工艺阀门的结构与特点来进行设计呢?...
  5. 一位做了5年Java开发的读者,跟我说面试题都不会答···
  6. JDK11+Maven开发JavaFx启动问题:java.lang.IllegalAccessError: class com.sun.javafx.fxml.FXMLLoaderHelper
  7. Jquery 强大的表单验证操作
  8. 项目中发现 unity运行挂机放那大约半小时,运行项目变得越来越卡顿
  9. Hi3798 PWM输出控制背光
  10. find linux 指定后缀_Linux下备份目录下指定的某些后缀文件
  11. 为了相同的前缀-麦迪时刻
  12. IPD解读——市场管理(MM)方法论
  13. rush learn note
  14. 检测工具进阶——结合静态分析的动态分析工具论文分享
  15. 收付款单提交时分录自动清空
  16. warframe在路由器上添加虚拟服务器,卡结算warframe方法
  17. shell习题-27
  18. 大端和小端的区别和判断
  19. Python实战——选择最佳旅游攻略,让旅游更加便捷(爬虫实战)
  20. 基于RGB-D数据的语义建图

热门文章

  1. 机器人路径规划_人工蜂群算法
  2. android创建平板模拟器,模拟器创建
  3. 怎样把本地文档共享至服务器上,利用云服务器共享本地文件
  4. 联合国儿童基金会宣布与微软达成新合作
  5. 昨天在洛阳,也就是阴历十月一日,晚上有在自家门前烧纸的,有点好奇,今天知道了
  6. 简易版计算器APP开发
  7. Weka数据挖掘——选择属性
  8. python源文件改写_Python源文件改写.编写一个程序,读取一个Python源程序,将文件中所有除保留字外的小写字母换成大写字母...
  9. 为什么买入不了创业版_为什么我买不了创业板?创业板开户有什么条件
  10. docker之数据挂载端口暴漏