P5484 [JLOI2011] 基因补全

P5484 [JLOI2011] 基因补全

拿到这题第一眼:kmp?第二眼:ac自动机?沉思5分钟后:不对……

我们思考这是怎么一个问题:求T串在S串中所有子串的匹配次数

这竟然是道欢乐dp题,记dp[i][j]为S串考虑到i,T串以j结尾的总匹配数,显然有dp[i][t[j]]+=dp[i-1][t[j-1]]。

但是我们发现这题的方案可能有很多,__int128都能爆的那种,所以我们要整高精度

然后这题就做完了

Code:

#include<bits/stdc++.h>
const int N=3005;
using namespace std;
struct ANS{
char val[N];
int cnt;
}dp[N];
int f[N];
inline void add(ANS &a,ANS b)
{
a.cnt=b.cnt>a.cnt ? b.cnt : a.cnt;
for(int i=1;i<=a.cnt;i++)
{
a.val[i]+=b.val[i];
a.val[i+1]+=a.val[i]/10;
a.val[i]%=10;
}
a.cnt+=a.val[a.cnt+1] ? 1 : 0;
}
void init(ANS &a)
{
for(int i=0;i<N;i++){a.val[i]=0;}
a.cnt=1;
}
int n,m;
char s[N],t[N];
int a[N],b[N];
map<char,char> tans;
map<char,int> id;
int pos[5][N],cnt[5];
void work()
{
cin>>n>>m;
//A T C G
//1 2 3 4
tans['A']='T';tans['T']='A';
tans['C']='G';tans['G']='C';
id['A']=1,id['T']=2,id['C']=3,id['G']=4;
scanf("%s",s+1);for(int i=1;i<=n;i++){s[i]=tans[s[i]];}
scanf("%s",t+1);
for(int i=1;i<=n;i++){a[i]=id[s[i]];}
for(int i=1;i<=m;i++){b[i]=id[t[i]];}
for(int i=1;i<=m;i++){pos[b[i]][++cnt[b[i]]]=i;init(dp[i]);}
init(dp[0]);
dp[0].val[1]=1;
//f[0]=1;
for(int i=1;i<=n;i++)
{
for(int j=cnt[a[i]];j;j--)
{
int x=pos[a[i]][j];
add(dp[x],dp[x-1]);
//f[x]+=f[x-1];
}
//cout<<f[m]<<"\n";
}
for(int i=dp[m].cnt;i;i--)
{
putchar('0'+dp[m].val[i]);
}
}
int main()
{
//freopen("1.in","r",stdin);freopen("gen.out","w",stdout);
work();
return 0;
}
posted @   liuboom  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示