• hdu1080 DP(类最长公共子序列)


    题意,有两个字符串,分别由四个字母构成,字母之间有不同的相似度,允许在两个字符串都按原顺序排列的情况下进行字母与字母之间的匹配,也可以让字母与空格匹配,即相当于在字符串中间加空格来一一匹配,每个字母与空格也有相应的相似度,但空格不能和空格匹配。问当给出两个字符串时,求它们的最大相似度。

    我一开始的想法也是想类似于最长公共子序列的做法,只是将匹配数变成了一个权值,总的相似度。这个方向是正确的,但是我却在细节上犯了糊涂,我一直在考虑当第一条链的第 i 个和第二条的第 j 个相匹配,这样的情况,从前面的各种情况转移到这里。但事实上,其实原本就该想到,最长公共子序列的状态转移也是对于匹配完第一条的第 i 个和第二条的第 j 个,而不是这两个恰好匹配。这样做反而容易进行状态转移。

    状态转移关系如下:

    dp [ i ] [ j ] 表示匹配完第一条的第 i 个和第二条的第 j 个(均可以与空格进行匹配);

    ① dp [ i - 1 ] [ j ] + v (第一条第 i 个与空格匹配后增加的相似度) ,当该值大于 dp 原值时就用它优化 dp;

    ② dp [ i ] [ j - 1 ] + v (第二条第 j 个与空格匹配后增加的相似度) ,当该值大于 dp 原值时就用它优化 dp;

    ③ dp [ i - 1 ] [ j - 1 ] + v(第一条第 i 个与第二条第 j 个匹配后增加的相似度) ,当该值大于 dp 原值时就用它优化 dp;

    这样就行了;

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 #define max(a,b) a>b?a:b
     5 #define INF 100000
     6 using namespace std;
     7 int v[5][5]={{0,-3,-4,-2,-1},{-3,5,-1,-2,-1},{-4,-1,5,-3,-2},{-2,-2,-3,5,-2},{-1,-1,-2,-2,5}};
     8 int dp[105][105];
     9 int s1[105],s2[1059];
    10 
    11 int main(){
    12     int n;
    13     while(scanf("%d",&n)!=EOF){
    14         for(int q=1;q<=n;q++){
    15             memset(s1,0,sizeof(s1));
    16             memset(s2,0,sizeof(s2));
    17             int l1,l2;
    18             scanf("%d",&l1);
    19             int i,j;
    20             getchar();
    21             char a;
    22             dp[0][0]=0;
    23             for(i=1;i<=l1;i++){
    24                 a=getchar();
    25                 if(a=='A') s1[i]=1;
    26                 else if(a=='C') s1[i]=2;
    27                 else if(a=='G') s1[i]=3;
    28                 else if(a=='T') s1[i]=4;
    29                 dp[i][0]=dp[i-1][0]+v[s1[i]][0];
    30             }
    31             scanf("%d",&l2);
    32             getchar();
    33             for(i=1;i<=l2;i++){
    34                 a=getchar();
    35                 if(a=='A') s2[i]=1;
    36                 else if(a=='C') s2[i]=2;
    37                 else if(a=='G') s2[i]=3;
    38                 else if(a=='T') s2[i]=4;
    39                 dp[0][i]=dp[0][i-1]+v[0][s2[i]];
    40             }
    41             int k;
    42 /*
    43             printf("s1:");
    44             for(i=1;i<=l1;i++)printf("%d",s1[i]);
    45             printf("
    ");
    46             printf("s2:");
    47             for(i=1;i<=l2;i++)printf("%d",s2[i]);
    48             printf("
    ");
    49 */
    50             for(i=1;i<=l1;i++){
    51                 for(j=1;j<=l2;j++){
    52                     dp[i][j]=-INF;
    53                     dp[i][j]=max(dp[i][j],dp[i-1][j]+v[s1[i]][0]);
    54                     dp[i][j]=max(dp[i][j],dp[i][j-1]+v[0][s2[j]]);
    55                     dp[i][j]=max(dp[i][j],dp[i-1][j-1]+v[s1[i]][s2[j]]);
    56                 }
    57             }
    58             printf("%d
    ",dp[l1][l2]);
    59         }
    60     }
    61     return 0;
    62 }
    View Code
  • 相关阅读:
    magent + memcached 集群测试
    SQL Server 2000/2005检测存储过程名是否存在,存在删除
    ASP.NET在线用户列表精确版——解决用户意外退出在线列表无法及时更新问题
    使用asp.net/c# ajax 乱码的解决办法
    清空删除mssql数据库日志原文网址:http://admin.88443.net/article.
    net2.0下的简繁转换
    创建和注册自定义 httpModules 模块
    监控用户是否关闭浏览器
    Asp.net(Ajax)表单验证 函数包
    IE自带的网页过渡特效
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4309603.html
Copyright © 2020-2023  润新知