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; }