【算法基础(第五版)】例3.13 序列对准求最小值
来源:互联网 发布:淘宝秒杀需要刷新 编辑:程序博客网 时间:2024/05/18 01:36
算法基础(第五版)之序列对准
题目背景,给出两个同源DNA序列,不匹配罚一分,有缝隙(即一个字母对应一个短线)罚两分,例如:
对于序列AACAGTTACC和TAAGGTCA,
-AACAGTTACC和TAA-GGT–CA是一种对准方式,
AACAGTTACC和TA-AGGT-CA是另一种对准方式,第一种罚分数为1*2+2*4=10,第二种为1*3+2*2=7,第二种方式比第一种好,对准方式有很多种,如何找到最好的对准方式及求出最小罚分值。
思路:m[i][j]表示从s1的第i个位置和从s2的第j个位置开始对准最低罚分值,进而得到递推公式
若s1[i]==s2[j],
则m[i][j]=min(m[i+1][j]+2,m[i][j+1]+2,m[i+1][j+1])
若不等,
则m[i][j]=min(m[i+1][j]+2,m[i][j+1]+2,m[i+1][j+1]+1)
解释如下:对于s1的第i个字母和s2[j],可以s1[i]与s2[j]对准,可以S1[i]与‘-’对准,和s2[j]与‘-’对准。
从m[len1][len2]开始斜对角线递推至m[0][0]即为总最小惩罚值,路径根据打表之后从m[0][0]对比变化得知。代码如下:
#include<stdio.h>#include<string.h>#include<string>using namespace std;#define inf 0x3f3f3f3fint main(){ char s1[50]; char s2[50]; scanf("%s%s",s1,s2); int m[55][55]; int strlen1=strlen(s1); int strlen2=strlen(s2); for(int i=0;i<55;i++) { for(int j=0;j<55;j++) { m[i][j]=inf; } } //初始边界值,当s1字母对准至边界后,只能拿‘-’对准s2,惩罚值为后面字母的个数 for(int i=0;i<=strlen2;i++) { m[i][strlen1]=(strlen2-i)*2; } for(int i=0;i<=strlen1;i++) { m[strlen2][i]=(strlen1-i)*2; } //对角线法求dp表 for(int i=strlen1-2;i>=0;i--) { int x=strlen2-1; int y=i+1; while(y<strlen1) { //printf("%d %d\n",x,y); m[x][y]=min(m[x+1][y],m[x][y+1])+2; if(s1[y]==s2[x]) { m[x][y]=min(m[x][y],m[x+1][y+1]); } else { m[x][y]=min(m[x][y],m[x+1][y+1]+1); } x--; y++; } } for(int i=strlen2-1;i>=0;i--) { int x=i; int y=0; while(x>=0) { m[x][y]=min(m[x+1][y],m[x][y+1])+2; if(s1[y]==s2[x]) { m[x][y]=min(m[x][y],m[x+1][y+1]); } else m[x][y]=min(m[x][y],m[x+1][y+1]+1); x--; y++; } } //输出最小值 printf("%d\n",m[0][0]); //根据表格寻找对准路径 int xx=0,yy=0; int ss1[55],ss2[55]; int cnt1=0,cnt2=0; while(xx!=strlen2||yy!=strlen1) { if(m[xx][yy]==m[xx+1][yy]+2) { ss1[cnt1++]=yy; // printf("s1:%d ",yy); xx++; } else if(m[xx][yy]==m[xx][yy+1]+2) { ss2[cnt2++]=xx; //printf("s2:%d ",xx); yy++; } else { xx++; yy++; } } int ii=0; for(int i=0;i<strlen1;i++) { if(ii<cnt1&&ss1[ii]==i) { printf("-"); ii++; } printf("%c",s1[i]); } printf("\n"); for(int i=0;i<strlen2;i++) { if(ii<cnt2&&ss2[ii]==i) { printf("-"); ii++; } printf("%c",s2[i]); } printf("\n"); }/*TAAGGTCAAACAGTTACCTAAGGTCA*/
感谢队友的强烈监督!
阅读全文
0 0
- 【算法基础(第五版)】例3.13 序列对准求最小值
- (1544): 序列划分(求极大值的最小值)&(1233): 【基础算法】 书的复制
- 算法3.12 使用分治法的序列对准
- 求旋转序列的最小值
- 递归求序列最大最小值
- 求序列的最大最小值
- 基础算法(1):最值(最大值,最小值,同时求最大值和最小值)
- 基础算法(1):最值(最大值,最小值,同时求最大值和最小值)
- 【基础算法】求最长公共子序列
- 求最大最小值的O(3n/2)算法
- 字符串算法——求最长公共子序列(摘自算法基础,没有代码)
- 动态规划——序列对准
- 求最大、最小值的高效算法
- 常用算法_求最小值Test1
- 带求最小值的堆栈算法
- 算法--求数组中的最大和最小值
- RMQ算法 快速求区间最大最小值
- 遗传算法求二元函数的最小值
- java内存管理与继承
- mysql group_concat 的分组,以及输出到Java的String
- 【代码库】日期工具类
- 判断JS数据类型的四种方法
- jde 判断闰年,破月以及计算总租金(破月的话最后一个月要按实际天数来算!)
- 【算法基础(第五版)】例3.13 序列对准求最小值
- Tampermonkey安装与使用
- Spring 中Bean的生命周期
- python中导入win32com.client出错问题
- 【英语学习】Why we can't learn English as we want?
- hdu 4770 Lights Against Dudely(状态压缩dfs)
- IntelliJ IDEA Default Keymap
- 练习17
- HDU