您的位置:首页 > 其它

简单?dp

2016-08-16 19:35 246 查看
链接http://www.luogu.org/problem/show?pid=1140

题意:给你两个基因,每个基因可以两两对应,也可以一个对应空。不同的对应会得到不同的数字,求最大的对应和是多少

解析:dp。三个dp转移方程

1.dp[i][j] = dp[i - 1][j - 1] + match(a[i],b[j])注意此处不是max。

2.dp[i][j] = max(dp[i][j],dp[i - 1][j] + mapp[match(a[i])][4])第i个的对应为空

3.dp[i][j] = max(dp[i][j],dp[i][j - 1] + mapp[4][match(b[j])])第j个对应为空。

需要进行边界处理,先把i = 0和j = 0全都对应为空的处理好、

两个程序、#include <iostream>
#include <cstdio>
#include <cstring>
#include <sstream>
#include <string>
#include <algorithm>
#include <list>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <cstdlib>
using namespace std;
int mapp[5][5] = {{5,-1,-2,-1,-3},{-1,5,-3,-2,-4},{-2,-3,5,-2,-2},{-1,-2,-2,5,-1},{-3,-4,-2,-1,-1000000000}};
char a[105],b[105];

int dp[105][105];
int match(char c)
{
if(c == 'A')
return 0;
if(c == 'C')
return 1;
if(c == 'G')
return 2;
if(c == 'T')
return 3;
return 4;
}
int main()
{
// freopen("in.txt","r",stdin);
int n,m;
scanf("%d%s",&n,a + 1);
scanf("%d%s",&m,b + 1);

for(int i = 1; i <= n; i ++)
{
dp[i][0] = dp[i - 1][0] + mapp[match(a[i])][4];//边界处理,此处的值是与后面的处理不一样的。这种边界不能取最大值,因为它本身是没有值的,就是不是从上衣个状态转移过来的。
//如果非得要合并在一起,需要把dp初始值设为无限小。
}
for(int i = 1; i <= m; i ++)
{
dp[0][i] = dp[0][i - 1] + mapp[4][match(b[i])];
}

for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= m; j ++)
{

dp[i][j] =dp[i - 1][j - 1] + mapp[match(a[i])][match(b[j])];
dp[i][j] = max(dp[i][j],dp[i - 1][j] + mapp[match(a[i])][4]);
dp[i][j] = max(dp[i][j],dp[i][j - 1] + mapp[4][match(b[j])]);
}
}

cout<<dp
[m] <<endl;
return 0;
}

#include <iostream>
#include <cstdio>
#include <cstring>
#include <sstream>
#include <string>
#include <algorithm>
#include <list>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <cstdlib>
using namespace std;
int mapp[5][5] = {{5,-1,-2,-1,-3},{-1,5,-3,-2,-4},{-2,-3,5,-2,-2},{-1,-2,-2,5,-1},{-3,-4,-2,-1,-1000000000}};
char a[105],b[105];

int dp[105][105];
int match(char c)
{
if(c == 'A')
return 0;
if(c == 'C')
return 1;
if(c == 'G')
return 2;
if(c == 'T')
return 3;
return 4;
}
int main()
{
//freopen("in.txt","r",stdin);
int n,m;
scanf("%d%s",&n,a + 1);
scanf("%d%s",&m,b + 1);

for(int i = 0; i <= n; i ++)
{
for(int j = 0; j <= m; j ++)
{
dp[i][j] = -1000000000;

if(i == 0 && j == 0)
{

dp[0][0] = 0;
continue;
}
if(i !=0 && j != 0)
dp[i][j] =dp[i - 1][j - 1] + mapp[match(a[i])][match(b[j])];
if(i != 0)
dp[i][j] = max(dp[i][j],dp[i - 1][j] + mapp[match(a[i])][4]);
if(j != 0)
dp[i][j] = max(dp[i][j],dp[i][j - 1] + mapp[4][match(b[j])]);
}
}

cout<<dp
[m] <<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息