#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm> using namespace std;
/*dp,poj1080*/ int dp[][];//动态规划数据存放
int map[][];//用来存放原始数据 void map_init()
{
map['A']['A']=map['C']['C']=map['G']['G']=map['T']['T']=;
map['A']['C']=map['C']['A']=map['A']['T']=map['T']['A']=map['T'][' ']=map[' ']['T']=-;
map['A']['G']=map['G']['A']=map['C']['T']=map['T']['C']=map['G']['T']=map['T']['G']=map['G'][' ']=map[' ']['G']=-;
map['A'][' ']=map[' ']['A']=map['G']['C']=map['C']['G']=-;
map['C'][' ']=map[' ']['C']=-;
} int max_X3(int a,int b,int c)
{
if(a>b)
{
if(a>c)
return a;
else
return c;
}
else
{
if(b>c)
return b;
else
return c;
}
} int main()
{
int y;//全局次数
int i,j;//循环变量
int a,b;//用户输入
char str1[];
char str2[]; //初始化
map_init(); cin>>y;
while (y--)
{
scanf("%d %s",&a,str1);
scanf("%d %s",&b,str2); //初始化第一行第一列
dp[][]=;
for (i = ; i < a; i++)
dp[][i+] = dp[][i] + map[str1[i]][' ']; for (j = ; j < b; j++)
dp[j+][] = dp[j][] + map[str2[j]][' ']; for (i = ; i <= a; i++)
{
for (j = ; j <= b; j++)
{
dp[j][i] = max_X3(dp[j-][i-]+map[str2[j-]][str1[i-]],
dp[j-][i]+map[str2[j-]][' '],
dp[j][i-]+map[str1[i-]][' ']);
}
} cout<<dp[b][a]<<endl;
}
return ;
}

先上代码,然后说明。

首先对于动态规划到现在的理解,只是现阶段的理解。动态规划下面用dp代替。

要点:

1、一个问题可以被分成多个相同的子问题,子问题和原问题差别只有数据规模,总结就是大化小。

2、这个问题的解可以由子问题的解得出,总结就是用已经有的小解得出最后的解。

3、经常用一个二维数组去保存已经求出的解,之后要是用到就可以直接取不用计算,总结就是记录已经解过的方程的解,不做相同的无用功。

4、状态转移方程,其中的状态,初始值,这些都要考虑清楚。

对于模型,等我做过10道题目熟练之后再说吧,现在给出还为时过早。

题目:

首先明确状态,问问自己两个字符串对比有几种状态?下面用AB两个字符表示两个字符串

1、A的这个字母和B相同

2、A的这个字母和B不同,A和-对应

3、A的这个字母和B不同,B和-对应

最后出来的两个字符串一定是满足这个规则的。只有这三种状态。

那么状态转移方程呢?

1、明确目的,我们要求的是匹配的最后数字上面越大越好。

2、两个字母相同,那么是+5,其他都要减一个数,那么问题来了,这里千万不要以为相同就是最好的,如果这里认为相同就是最好的,那么你用的是贪心而不是dp了。

3、我们取之前的解为Y1,Y2,Y3,123对应上面三个状态,max(Y1+5,Y2-5,Y3-5)这里5是个虚数,可能是0也可能是负数。

4、要注意的有两点,第一,这个状态的之前那个状态的解,是不同的!如下面所示,如果我们处理第二个字符时候可能出现之前的情况就有下面三种

ATGC

GGGG

ATGC

-GGGG

-ATGC

GGGG

第二,Y1,Y2,Y3,是不同的,所以要取这三个值得max。

那么初始值呢?

初始值一般是二维数组的0行0列,这里要注意的是,这里的初始值不全是0,看看下面的情况

ATGC - - - -

- - - -GGGG

所以初始值应该是每一个字母都和空对应,而且要在之前那个值加上去,之前A和空对应如果是-3,那么T和空对应如果是-1,在二维数组中T这里的值应该是-4

最后输出二维数组中最右下角的值就是最后的解。

这里灵活之处是利用一个二维数组去保存了两个字母之间的关系,所以看起来代码特别清晰。

之后会对动态规划再细说的,这次就说这么多。

动态规划1-----------poj1080的更多相关文章

  1. POJ1080 Human Gene Functions 动态规划 LCS的变形

    题意读了半年,唉,给你两串字符,然后长度不同,你能够用'-'把它们补成同样长度,补在哪里取决于得分,它会给你一个得分表,问你最大得分 跟LCS非常像的DP数组 dp[i][j]表示第一个字符串取第i个 ...

  2. 【poj1080】 Human Gene Functions

    http://poj.org/problem?id=1080 (题目链接) 题意 给出两个只包含字母ACGT的字符串s1.s2,可以在两个字符串中插入字符“-”,使得s1与s2的相似度最大. Solu ...

  3. 增强学习(三)----- MDP的动态规划解法

    上一篇我们已经说到了,增强学习的目的就是求解马尔可夫决策过程(MDP)的最优策略,使其在任意初始状态下,都能获得最大的Vπ值.(本文不考虑非马尔可夫环境和不完全可观测马尔可夫决策过程(POMDP)中的 ...

  4. 简单动态规划-LeetCode198

    题目:House Robber You are a professional robber planning to rob houses along a street. Each house has ...

  5. 动态规划 Dynamic Programming

    March 26, 2013 作者:Hawstein 出处:http://hawstein.com/posts/dp-novice-to-advanced.html 声明:本文采用以下协议进行授权: ...

  6. 动态规划之最长公共子序列(LCS)

    转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...

  7. C#动态规划查找两个字符串最大子串

     //动态规划查找两个字符串最大子串         public static string lcs(string word1, string word2)         {            ...

  8. C#递归、动态规划计算斐波那契数列

    //递归         public static long recurFib(int num)         {             if (num < 2)              ...

  9. 动态规划求最长公共子序列(Longest Common Subsequence, LCS)

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

随机推荐

  1. stm32时钟配置总结

    stm32时钟配置时钟源: 1,HSE(高速外部时钟)即常见的外接8M晶振方案: 2,HSI(高速内部时钟) 即8M内部振荡时钟方案: 3,LSE(低速外部时钟)即常见的32.768Khz晶振方案: ...

  2. Linux通过XAMPP集成软件包搭建LAMPP环境

    前面介绍过一篇“Linux手动搭建LAMP环境”,今天再来整理一篇“Linux通过XAMPP集成软件包搭建LAMPP环境”. 其实当初整理通过XAMPP集成软件包搭建LAMPP环境的原因是这样的: 自 ...

  3. First blogs start

    这是我第一次写博客笔记,为了更好的成长,从现在开始我的博客记录. 我是从事linux运维的,到目前为止,已经有2年的工作经验了. 希望从此以后我能够坚持每天记录下点点滴滴.

  4. HDU1115--Lifting the Stone(求凸多边形的重心)

    Problem Description There are many secret openings in the floor which are covered by a big heavy sto ...

  5. 只能在执行 Render() 的过程中调用 RegisterForEventValidation

    当用GridView导出Execl的时候,会发生只能在执行 Render() 的过程中调用 RegisterForEventValidation的错误提示.有两种方法可以解决以上问题: 1.修改web ...

  6. openwrt下加载snmp模块

    加snmp模块到openwrt中去 1.下载snmp的解压包文件 net-snmp-5.4.2.1.tar.gz 下载地址为:http://www.net-snmp.org/download.html ...

  7. CentOS 7 BIND 搭建

    域名查找顺序 设置 /etc/host.conf 1. bind 安装 $ yum install bind bind-utilsnslookup (name server lookup) 在bind ...

  8. MySQL 出现 The table is full 的解决方法【转】

    [MySQL FAQ]系列 — 你所不知的table is full那些事 时间 2014-08-21 12:18:56  MySQL中文网 原文  http://imysql.com/2014/08 ...

  9. shell命令一行代码搞定【转】

    查看文件内容-while: cat 1.txt|while read line;do echo $line;done while read line; do echo $line; done < ...

  10. Vim常用命令【转载】

    下面基本是vim的基本用法,刚开始学习可能有些不习惯.但贵在坚持,即使不习惯,也要坚持使用,做到不经过思考就能操作,你会发现真的很方便.很多操作可以通过不同的命令达到,我这里只列出常用的. 基础命令 ...