POJ-1080 Human Gene Functions 类似于LCS
题目链接:http://poj.org/problem?id=1080
题目大意是匹配DNA分子,使得DNA可能性最大。开始自己想的是O(n^3)的算法,构造字符串,然后在状态转移,结果POJ过了,但是HDOJ WA,果然POJ的数据比较水,但是现在还没有想出问题在哪里(明天把问题找出来)。其实这个类似于LIS,基本模型:E[i,j]=opt{D[i-1,j]+xi,D[i,j-1]+yj,D[i-1][j-1]+zij}。
POJ AC/HDOJ WA代码:
1 //STATUS:C++_POJ AC/HDOJ WA_79MS_584KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #include<vector> 10 #include<queue> 11 #include<stack> 12 using namespace std; 13 #define LL __int64 14 #define pii pair<int,int> 15 #define Max(a,b) ((a)>(b)?(a):(b)) 16 #define Min(a,b) ((a)<(b)?(a):(b)) 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define lson l,mid,rt<<1 19 #define rson mid+1,r,rt<<1|1 20 const int N=310,INF=0x3f3f3f3f,MOD=1999997; 21 const LL LLNF=0x3f3f3f3f3f3f3f3fLL; 22 23 char s1[N],s2[N]; 24 int f[N][N],ma[N][N]; 25 int a,b,T,len1,len2; 26 27 void get(char *s,int a,int b) 28 { 29 int i; 30 char st[N]; 31 for(i=0;i<a;i++)st[i]=s[i]; 32 for(i=0;i<b;i++)s[i]=0; 33 for(;i<a+b;i++)s[i]=st[i-b]; 34 for(;i<2*a+b;i++)s[i]=0; 35 } 36 37 int main() 38 { 39 // freopen("in.txt","r",stdin); 40 int i,j,k,t; 41 ma['A']['A']=5,ma['A']['C']=-1,ma['A']['G']=-2,ma['A']['T']=-1,ma['A'][0]=-3; 42 ma['C']['A']=-1,ma['C']['C']=5,ma['C']['G']=-3,ma['C']['T']=-2,ma['C'][0]=-4; 43 ma['G']['A']=-2,ma['G']['C']=-3,ma['G']['G']=5,ma['G']['T']=-2,ma['G'][0]=-2; 44 ma['T']['A']=-1,ma['T']['C']=-2,ma['T']['G']=-2,ma['T']['T']=5,ma['T'][0]=-1; 45 ma[0]['A']=-3,ma[0]['C']=-4,ma[0]['G']=-2,ma[0]['T']=-1,ma[0][0]=0; 46 scanf("%d",&T); 47 while(T--){ 48 mem(f,-INF); 49 scanf("%d%s%d%s",&a,s1,&b,s2); 50 len1=a+2*b;len2=b+2*a; 51 get(s1,a,b); 52 get(s2,b,a); 53 54 for(i=0;i<a;i++)f[0][i]=0; 55 for(t=0;i<a+b;i++){f[0][i]=ma[s1[0]][s2[i]]+t;t+=ma[0][s2[i]];} 56 for(t=f[0][i-1];i<len2;i++)f[0][i]=t; 57 for(i=0;i<len1-1;i++){ 58 for(j=0;j<len2;j++){ 59 f[i+1][j]=Max(f[i+1][j],f[i][j]+ma[s1[i+1]][0]); 60 for(t=0,k=j+1;k<len2;k++){ 61 f[i+1][k]=Max(f[i+1][k],f[i][j]+ma[s1[i+1]][s2[k]]+t); 62 t+=ma[0][s2[k]]; 63 } 64 } 65 } 66 67 printf("%d\n",f[len1-1][len2-1]); 68 } 69 return 0; 70 }
正解:
1 //Writen by others 2 #include<iostream> 3 #include <string> 4 #include <cstring> 5 using namespace std; 6 int map[200][200],dp[200][200]; 7 int max(int a,int b,int c){ if(a<b)a=b;if(a<c)a=c;return a;} 8 int main() 9 { 10 map['A']['C']=map['C']['A']=-1,map['A']['G']=map['G']['A']=-2,map['A']['T']=map['T']['A']=-1,map['C']['G']=map['G']['C']=-3,map['C']['T']=map['T']['C']=-2,map['T']['G']=map['G']['T']=-2,map['A']['-']=map['-']['A']=-3,map['C']['-']=map['-']['C']=-4,map['G']['-']=map['-']['G']=-2,map['T']['-']=map['-']['T']=-1,map['A']['A']=map['C']['C']=map['T']['T']=map['G']['G']=5,map['-']['-']=0; 11 int T,n1,n2; 12 cin>>T; 13 while(T--) 14 { 15 string s1,s2,t; 16 cin>>n1>>s1>>n2>>s2; 17 memset(dp,0,sizeof(dp)); 18 for(int i=1;i<=n1;++i)dp[i][0]=dp[i-1][0]+map[s1[i-1]]['-']; 19 for(int i=1;i<=n2;++i)dp[0][i]=dp[0][i-1]+map['-'][s2[i-1]]; 20 for(int i=1;i<=n1;++i) 21 for(int j=1;j<=n2;++j) 22 { 23 dp[i][j]=max(dp[i-1][j-1]+map[s1[i-1]][s2[j-1]],dp[i-1][j]+map[s1[i-1]]['-'],dp[i][j-1]+map[s2[j-1]]['-']); 24 } 25 cout<<dp[n1][n2]<<endl; 26 } 27 return 0; 28 }