poj1080 每天一道dp题打卡

poj1080 每天一道dp题打卡
题目:http://poj.org/problem?id=1080

思路:dp[i][j]表示第一个串的第i个和第二个串的第j个匹配时的最大匹配值,这样转移方程也很容易得到了。

AC代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<cctype>
#include<set>
#include<stack>
#include<map>
#include<queue>
#include<vector>
#include<algorithm>
#define endl '\n'
#define css(n) cout<<setiosflags(ios::fixed)<<setprecision(n); 
#define sd(a) scanf("%d",&a)
#define sld(a) scanf("%lld",&a)
#define m(a,b) memset(a,b,sizeof a)
#define pb push_back 
#define lson id<<1
#define rson id<<1|1
typedef long long ll;
using namespace std;
const int maxn = 1005,modd = 1e9 + 7,inf = 0x3f3f3f3f,INF = 0x7fffffff;
inline ll min(ll a,ll b){return a < b ? a : b;}
inline ll max(ll a,ll b){return a > b ? a : b;}
inline ll gcd(ll a,ll b){ return b==0? a: gcd(b,a%b); }
inline ll exgcd(ll a,ll b,ll &x,ll &y){ ll d; (b==0? (x=1,y=0,d=a): (d=exgcd(b,a%b,y,x),y-=a/b*x)); return d; }
inline ll qpow(ll a,ll n){ll sum=1;while(n){if(n&1)sum=sum*a%modd;a=a*a%modd;n>>=1;}return sum;}
inline ll qmul(ll a,ll n){ll sum=0;while(n){if(n&1)sum=(sum+a)%modd;a=(a+a)%modd;n>>=1;}return sum;}
inline ll inv(ll a) {return qpow(a,modd-2);}//求逆元 
inline ll madd(ll a,ll b){return (a%modd+b%modd)%modd;}//加后取模 
inline ll mmul(ll a,ll b){return a%modd * b%modd;}//乘后取模 
int n,m,t;
int score[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}; 
map<char,int> mp;
char s1[105],s2[105];
int dp[200][200];
int main()
{
/*	std::ios::sync_with_stdio(0);
	std::cin.tie(0);std::cout.tie(0);*/
	mp['A']=0;mp['C']=1;mp['G']=2;mp['T']=3;mp['-']=4;
	sd(t);
	while(t--)
	{
		memset(dp,-0x3f,sizeof(dp));
		scanf("%d %s",&n,s1+1);
		scanf("%d %s",&m,s2+1);
		dp[0][0]=0;
		for(int i=1;i<=n;i++)
		dp[i][0]=dp[i-1][0]+score[mp[s1[i]]][mp['-']];
		for(int j=1;j<=m;j++)
		dp[0][j]=dp[0][j-1]+score[mp['-']][mp[s2[j]]];
		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]+score[mp[s1[i]]][mp['-']]);
			dp[i][j]=max(dp[i][j],dp[i][j-1]+score[mp['-']][mp[s2[j]]]);
			dp[i][j]=max(dp[i][j],dp[i-1][j-1]+score[mp[s1[i]]][mp[s2[j]]]);
		}
		printf("%d\n",dp[n][m]);
	 } 
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值