poj 1080

本文探讨了一种基于LCS思想的字符串匹配问题扩展,通过引入搭配权值,实现不同字符之间的组合优化。详细阐述了解题思路及关键步骤,并提供了代码实现。适合对算法优化与字符串处理感兴趣的读者。

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

       题意很好懂,不多说。

       此题是LCS问题的扩展,众所周知LCS求的是最长长度,而这里只是用一个搭配权值代替了长度而已,因此可以借用LCS的思想来求解。c[i][j]为两个字符串在分别在长度为i和j时所得的最长长度,由于可以首字母与‘-’相搭配,因此要有一个初始化过程(可见代码)。然后是状态转移,对于每个字符串的每个字符,其可以和‘-’搭配,也可以和另一个字符串的字符搭配,因此会有三种情况(之前合并成一种来考虑,结果做了很久都做不出。。。)。最后输出c[len1][len2]即可。

       以下是代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int M=200;
const int inf=1<<29;
int c[M][M];
int a[M],b[M];
int dir[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};
char s[M],t[M];
char dic[5]={'A','C','G','T','-'};
int len1,len2;

int getMark(char ch)
{
	for(int i=0;i<5;i++)
		if(dic[i]==ch) return i;
}

void LCS()
{
	int i,j;
	for(i=0;i<=len1;i++)
	{
		for(j=0;j<=len2;j++)
			c[i][j]=-inf;
	}
	c[0][0]=0;
	for(i=1;i<=len2;i++)
		c[0][i]=c[0][i-1]+dir[b[i]][4];
	for(i=1;i<=len1;i++)
		c[i][0]=c[i-1][0]+dir[a[i]][4];
	for(i=0;i<=len1;i++)
	{
		for(j=0;j<=len2;j++)
		{
			if(c[i][j]+dir[a[i+1]][4]>c[i+1][j])
				c[i+1][j]=c[i][j]+dir[a[i+1]][4];
			if(c[i][j]+dir[b[j+1]][4]>c[i][j+1])
				c[i][j+1]=c[i][j]+dir[b[j+1]][4];
			if(c[i][j]+dir[a[i+1]][b[j+1]]>c[i+1][j+1])
				c[i+1][j+1]=c[i][j]+dir[a[i+1]][b[j+1]];
		}
	}
}

int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int i;
		scanf("%d%s%d%s",&len1,s,&len2,t);
		for(i=0;i<len1;i++)
			a[i+1]=getMark(s[i]);
		for(i=0;i<len2;i++)
			b[i+1]=getMark(t[i]);
		LCS();
		printf("%d\n",c[len1][len2]);
	}
	return 0;
}


 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值