hdu 1080 打表+dp(最长公共子序列)

本文探讨使用动态规划算法解决序列匹配问题,包括初始化、状态转移方程的设定及复杂度分析。通过实例演示,详细解释了如何通过dp[i][j]来表示两个序列匹配到第i和j位的状态,并提供了代码实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先把题中给的表格打出来,然后dp

dp[i][j] = max ( dp[i-1][j-1]+a[s1[i]][s2[j]] , dp[i-1][j] + a[s1[i][' '] , dp[i][j-1] + a[' '][s2[j]] )

dp[i][j]代表两个序列当前匹配到几位,如果匹配的话转移如上第一种,如果不匹配有两种情况如上后两种情况,匹配空格

比较恶心的是打表打错了,搞了好久,,醉了....................................

弱啊

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#define MAX 107

using namespace std;

int t,n,m;
int dp[MAX][MAX];
int a[MAX][MAX];
char s1[MAX];
char s2[MAX];

int main ( )
{
    scanf ( "%d" , &t );
    a['A'-64]['A'-64]=a['C'-64]['C'-64]=a['G'-64]['G'-64]=a['T'-64]['T'-64]=5;
    a['A'-64]['C'-64]=a['C'-64]['A'-64]=a['A'-64]['T'-64]=a['T'-64]['A'-64]=-1;
    a['A'-64]['G'-64]=a['G'-64]['A'-64]=a['G'-64]['T'-64]=a['T'-64]['G'-64]=-2;
    a['C'-64]['G'-64]=a['G'-64]['C'-64]=-3;
    a['C'-64]['T'-64]=a['T'-64]['C'-64]=-2;
    a[0]['A'-64]=a['A'-64][0] = -3;
    a[0]['C'-64]=a['C'-64][0] = -4;
    a[0]['G'-64]=a['G'-64][0] = -2;
    a[0]['T'-64]=a['T'-64][0] = -1;
    while ( t-- )
    {
        scanf ( "%d" , &n );
        scanf ( "%s" , s1+1 );
        scanf ( "%d" , &m );
        scanf ( "%s" , s2+1 );
        memset ( dp , -0x3f , sizeof ( dp ) );
        dp[0][0] = 0;
        for ( int i = 1 ; i <= n ; i++ )
            dp[i][0] = dp[i-1][0] + a[s1[i]-64][0];
        for ( int i = 1 ; i <= m ; i++ )
            dp[0][i] = dp[0][i-1] + a[0][s2[i]-64];
        for ( int i = 1 ; i <= n ; i++ )
            for ( int j = 1 ; j <= m ; j++ )
            {
                dp[i][j] = max ( dp[i][j] , dp[i-1][j] + a[s1[i]-64][0] );
                dp[i][j] = max ( dp[i][j] , dp[i][j-1] + a[0][s2[j]-64] );
                dp[i][j] = max ( dp[i][j] , dp[i-1][j-1] + a[s1[i]-64][s2[j]-64] );
            }
        printf ( "%d\n" , dp[n][m] );
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值