地址:http://poj.org/problem?id=1080
题意:匹配两字符串,使得到得权值最大。
解题心得:
本题最重要是问题的初始化,不仅要令dp[0][0]=0;
而且要初始化dp数组的0行0列:
for(i=1;i<=l1;i++) dp[i][0]=dp[i-1][0]+score[p1[i]][0];
for(j=1;j<=l2;j++) dp[0][j]=dp[0][j-1]+score[0][p2[j]];
动态规划方程:
dp[i][j]=max(dp[i-1][j]+score[p1[i]][0],dp[i][j-1]+score[0][p2[j]],dp[i-1][j-1]+score[p1[i]][p2[j]]);
PS:就是在这个方程的最后一项score[p1[i]][p2[j]]刚开始写成了score[i][j],卡了我一天,不过最后我还是能找出错误,就说明了没有找不出的BUG,如果不能处理细节错误那么写再多的题也枉然!
#include<iostream>
#include<cstring>
using namespace std;
#define N 105
int score[5][5]={{-5,-3,-4,-2,-1},{-3,5,-1,-2,-1},{-4,-1,5,-3,-2},{-2,-2,-3,5,-2},{-1,-1,-2,-2,5}};
int dp[N][N];
void input(int l,int*p)
{
char a;
for(int i=1;i<=l;i++)
{
cin>>a;
switch(a)
{
case'A':p[i]=1;break;
case'C':p[i]=2;break;
case'G':p[i]=3;break;
case'T':p[i]=4;break;
}
}
}
int max(int a,int b,int c)
{
int k=a>b?a:b;
return k>c?k:c;
}
int main()
{
int i,j,t,l1,l2;
string s1,s2;
int *p1,*p2;
while(cin>>t)
{
while(t--)
{
//input
cin>>l1;
p1=new int[l1+1];
input(l1,p1);
cin>>l2;
p2=new int[l2+1];
input(l2,p2);
//initial
dp[0][0]=0;
for(i=1;i<=l1;i++)
dp[i][0]=dp[i-1][0]+score[p1[i]][0];
for(j=1;j<=l2;j++)
dp[0][j]=dp[0][j-1]+score[0][p2[j]];
//dp
for(i=1;i<=l1;i++)
for(j=1;j<=l2;j++)
{
dp[i][j]=max(dp[i-1][j]+score[p1[i]][0],dp[i][j-1]+score[0][p2[j]],dp[i-1][j-1]+score[p1[i]][p2[j]]);
}
cout<<dp[l1][l2]<<endl;
delete[] p1;
delete[] p2;
}
}
return 0;
}