HDOJ 1080

来源:互联网 发布:淘宝账号怎么实名认证 编辑:程序博客网 时间:2024/04/29 13:04

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1080

——————————————————————————————————————————————

题目思路:

法一:(比较快的经典办法)

dp[i][j] = max{dp[i-1][j-1]+a[i][j], dp[i-1][j] + a[i]['-'] ,dp[i][j-1] + a[j]['-'] }

就这三种情况,ij相对应,或者i跟空格,或者j跟空格。

dp[i][j] 表示的是当 1串用过i个字符和2串用过j个字符后的最大值。

法二:(我自己想出的笨办法)

dp[i][j] = max{ max{ dp[i-1][k] },max{dp[k][j-1]} }+a[i][j]

dp[i][j] 表示的是i和j 恰好对上的最大值。

这样需要在两个串最后各加一个'-',最后的结果是 dp['-']['-']。

这样的复杂度就有三次方了。

——————————————————————————————————————————————

题目细节:

这题wa了几次。

1、dp[i][j] = max(dp[i][j],dp[k][j-1]+m);  这句中,由于j可能为0,故当j为0的时候,数组下表越界了。但由于这是二维的数组,并没有报内存溢出的错误。固给出了莫名其妙的错误答案。

以后对于数组下标是否越界一定要特别检察一下。

2、初始化有误。dp[i][j] = max(dp[i][j],dp[i-1][k]+m); 这句话中,i最小为1,这时候下标是0,但k可能不是0。这种情况一开始我没有初始化,wa了。

以后递推时,对可能用到之前的各种数据,都要仔细检察一下是否初始化了。

——————————————————————————————————————————————

源代码:

法一:

#include <cstdio>#include <iostream>#include <cstring>using namespace std;#define INF 10000000#define min(a,b) ((a)>(b)?(b):(a))#define max(a,b) ((a)>(b)?(a):(b))#define maxn 110int map[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,0}};int find(char a,char b){    int i = 0,j = 0;    switch(a)    {        case 'A':i = 0;break;        case 'C':i = 1;break;        case 'G':i = 2;break;        case 'T':i = 3;break;        case '-':i = 4;break;    }    switch(b)    {        case 'A':j = 0;break;        case 'C':j = 1;break;        case 'G':j = 2;break;        case 'T':j = 3;break;        case '-':j = 4;break;    }    return map[i][j];}int main(){    //freopen("in.in", "r", stdin);   // freopen("out.txt","w",stdout);    int t = 0;    int len1 = 0,len2 = 0;    char s1[maxn],s2[maxn];    int dp[maxn][maxn];    int i = 0,j = 0;    scanf("%d",&t);    while(t--)    {        scanf("%d%s",&len1,s1+1);        scanf("%d%s",&len2,s2+1);        s1[0] = '-';        s2[0] = '-';        dp[0][0] = 0;        for(i = 1;i<=len2;i++)        {            dp[0][i] = 0;            for(j = i;j>=0;j--)              dp[0][i] += find(s2[j],'-');        }        for(i = 1;i<=len1;i++)        {            dp[i][0] = 0;            for(j = i;j>=0;j--)              dp[i][0] += find(s1[j],'-');        }        for(i = 1;i<=len1;i++)          for(j = 1;j<=len2;j++)              dp[i][j] = max(max(dp[i-1][j]+find(s1[i],'-'),dp[i][j-1]+find(s2[j],'-')),find(s1[i],s2[j])+dp[i-1][j-1]);          printf("%d\n",dp[len1][len2]);    }    return 0;}

法二:
#include <cstdio>#include <iostream>#include <cstring>using namespace std;#define INF 10000000#define min(a,b) ((a)>(b)?(b):(a))#define max(a,b) ((a)>(b)?(a):(b))#define maxn 110int map[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,0}};int find(char a,char b){    int i = 0,j = 0;    switch(a)    {        case 'A':i = 0;break;        case 'C':i = 1;break;        case 'G':i = 2;break;        case 'T':i = 3;break;        case '-':i = 4;break;    }    switch(b)    {        case 'A':j = 0;break;        case 'C':j = 1;break;        case 'G':j = 2;break;        case 'T':j = 3;break;        case '-':j = 4;break;    }    return map[i][j];}int main(){    //freopen("in.in", "r", stdin);   // freopen("out.txt","w",stdout);    int t = 0;    int len1 = 0,len2 = 0;    char s1[maxn],s2[maxn];    int dp[maxn][maxn];    int i = 0,j = 0,k = 0,p = 0;    scanf("%d",&t);    while(t--)    {        scanf("%d%s",&len1,s1+1);        scanf("%d%s",&len2,s2+1);        dp[0][0] = 0;        s1[++len1] = '-';        s2[++len2] = '-';        s1[0] = '-';        s2[0] = '-';        for(i = 1;i<=len2;i++)        {            dp[0][i] = 0;            for(j = i;j>=0;j--)              dp[0][i] += find(s2[j],'-');        }        for(i = 1;i<=len1;i++)          for(j = 0;j<=len2;j++)          {               dp[i][j] = -INF;               for(k = j-1;k>=0;k--)               {                  int m = 0;                  for(p = j-1;p>k;p--)                    m+=find(s2[p],'-');                  dp[i][j] = max(dp[i][j],dp[i-1][k]+m);               }               if(j>=1)               for(k = i-1;k>=0;k--)               {                   int m = 0;                   for(p = i-1;p>k;p--)                     m+=find(s1[p],'-');                   dp[i][j] = max(dp[i][j],dp[k][j-1]+m);               }               dp[i][j] += find(s1[i],s2[j]);              // printf("i = %d,j = %d   %d\n",i,j,dp[i][j]);          }          printf("%d\n",dp[len1][len2]);    }    return 0;}





原创粉丝点击