POJ 1080

来源:互联网 发布:吉林顺通网络的骗局 编辑:程序博客网 时间:2024/06/07 04:49
POJ 1080

题意:给出2列字符串,然后给出每对字符所含的值,要求你在字符之间添加 “-” 号使2组字符长度相等,然后每个相同位置字符为一对,计算值的总和,要求总和要最大。

设dp[ i ][ j ]为以a字符第i位置为结束和以b字符j位置为结束的最优解。

状态转移方程:

dp[ i ][ j ]=max( dp[ i-1 ][ j-1 ]+maps[ a[ i ] ][ b[ j ] ] , dp[ i-1 ][ j ]+maps[ '-' ][ a[ i ] ], dp[ i ][ j-1 ]+maps[ '-' ][ b[ i ] ] );//maps[ x ][ y ]为2字符的值。

mpas表打错了一个·····坑爹啊,找了很久才找得到,不算难的DP,原理大概跟最长公共字串一样,不够熟练,磨了一段时间才构建出来。

 

#include<iostream>#include<cstring>#include<cmath>#include<algorithm>#include<stdio.h>#include<string>#include<cstring>using namespace std;#define N 105int dp[N][N];char a[N],b[N];int maps[N][N];int la,lb;void deal(){maps['A']['A']=5;maps['A']['C']=maps['C']['A']=-1;maps['A']['G']=maps['G']['A']=-2;maps['A']['T']=maps['T']['A']=-1;maps['A']['-']=maps['-']['A']=-3;maps['C']['C']=5;maps['C']['G']=maps['G']['C']=-3;maps['C']['T']=maps['T']['C']=-2;maps['C']['-']=maps['-']['C']=-4;maps['G']['G']=5;maps['G']['T']=maps['T']['G']=-2;maps['G']['-']=maps['-']['G']=-2;maps['T']['T']=5;maps['T']['-']=maps['-']['T']=-1;}void move(char *x){for(int i=104;i>=0;i--){x[i]=x[i-1];}}int main(){deal();int t;cin>>t;while(t--){cin>>la;if(la!=0)cin>>a;cin>>lb;if(lb!=0)cin>>b;memset(dp,0,sizeof(dp));move(a);move(b);for(int i=1;i<=la;i++)dp[i][0]=dp[i-1][0]+maps['-'][a[i]];for(int i=1;i<=lb;i++)dp[0][i]=dp[0][i-1]+maps['-'][b[i]];for(int i=1;i<=la;i++){for(int j=1;j<=lb;j++){//cout<<a[i]<<' '<<b[i]<<' '<<maps[a[i]][b[j]]<<endl;dp[i][j]=dp[i-1][j-1]+maps[a[i]][b[j]];dp[i][j]=max(dp[i-1][j]+maps[a[i]]['-'],dp[i][j]);dp[i][j]=max(dp[i][j-1]+maps[b[j]]['-'],dp[i][j]);}}/*for(int i=0;i<=la;i++){for(int j=0;j<=lb;j++){if(j)cout<<"    ";cout<<dp[i][j];}cout<<endl;}*/cout<<dp[la][lb]<<endl;}   return 0;}


 

 

原创粉丝点击