hdu 4899 Hero meet devil

首先,LCS是可以在 O(nlogn) 下求出来的,只要将A串的元素x替换成x在B串中出现的所有位置的降序,最后求修改后的A串的LIS就可以了。
因为 n 很小,就可以直接状压维护在O(nlogn)求LIS时记录某个长度的子序列的最小结尾的数组了(如果该数出现,则置1)。预处理一下每个状态遇到A,T,C,G四个字母时会转变的状态,之后递推即可。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define clr(a) memset(a,0,sizeof(a))
typedef long long ll;
const ll md=1000000007;ll dp[2][70000],rs[1001];
char cz[20],tz[4]={'A','T','C','G'};int n,m,ts[70000][4];
int _le(int x){int r=0;for(;x;x>>=1)r+=(x&1);return r;};
int _cl(int x,int a){
    if(x&(1<<a))return x;
    for(a=1<<a,x^=a,a<<=1;x>=a&&!(x&a);a<<=1);
    return x&a?x^a:x;
};
void cl(){
    int i,j,a,b,d,c,q,t;scanf("%s %d",cz,&m);n=strlen(cz);
    clr(dp),c=0,q=1,dp[0][0]=1;
    for(d=1<<n,i=0;i<d;++i)for(j=0;j<4;++j){
        for(t=i,b=n-1;b>=0;--b)if(cz[b]==tz[j])t=_cl(t,b);
        ts[i][j]=t;
    }
    for(i=0;i<m;++i,swap(c,q))for(clr(dp[q]),a=0;a<d;++a)
        for(j=0;j<4;++j){
            dp[q][t=ts[a][j]]+=dp[c][a];if(dp[q][t]>=md)dp[q][t]-=md;
        }
    for(clr(rs),i=0;i<d;++i){rs[a=_le(i)]+=dp[c][i];if(rs[a]>=md)rs[a]-=md;}
    for(i=0;i<=n;printf("%I64d\n",rs[i++]));
};
int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
#endif
    int t;scanf("%d",&t);
    while(t--)cl();
    return 0;
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值