BZOJ 3864 Hero meet devil DP套DP

原创 2015年07月10日 09:30:50

题目大意:给定一个长度为n(n15)的基因序列S,求对于每个i(0in)有多少长度为m(m1000)的基因串T满足STLCSi

考虑LCS怎么求
fi,j表示T的前i位和S的前j位的LCS
我们发现每一行之和上一行的状态有关

那么在这个问题中,我们令fi,j表示T的前i位与SLCS状态的第i行为j的状态数
由于每一行相邻两数最多差1,因此状态数不会超过2n,用一个二进制数存储相邻两项的差值即可
预处理所有转移后直接DP,时间复杂度O(4n2n+4m2n)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MOD 1000000007
using namespace std;
const char letters[]={'A','C','G','T'};
int n,m;
char s[20];
int trans[1<<15][4],cnt[1<<15],f[2][1<<15];
void Pretreatment()
{
    int i,j,k;
    for(i=0;i<1<<n;i++)
    {
        static int f[20],g[20];
        for(j=1;j<=n;j++)
            f[j]=f[j-1]+(i&(1<<j-1)?1:0);
        cnt[i]=f[n];
        for(k=0;k<4;k++)
        {
            for(j=1;j<=n;j++)
            {
                g[j]=max(g[j-1],f[j]);
                if(letters[k]==s[j])
                    g[j]=max(g[j],f[j-1]+1);
            }
            trans[i][k]=0;
            for(j=1;j<=n;j++)
                if(g[j]-g[j-1])
                    trans[i][k]|=1<<j-1;
        }

    }
}
int main()
{
    int T,i,j,k;
    for(cin>>T;T;T--)
    {
        scanf("%s%d",s+1,&m);
        n=strlen(s+1);
        Pretreatment();
        memset(f,0,sizeof f);
        f[0][0]=1;
        for(i=1;i<=m;i++)
        {
            memset(f[i&1],0,sizeof(f[0][0])<<15);
            for(j=0;j<1<<n;j++)
                for(k=0;k<4;k++)
                    (f[i&1][trans[j][k]]+=f[~i&1][j])%=MOD;
        }
        static int ans[20];
        memset(ans,0,sizeof ans);
        for(i=0;i<1<<n;i++)
            (ans[cnt[i]]+=f[m&1][i])%=MOD;
        for(i=0;i<=n;i++)
            printf("%d\n",ans[i]);
    }
    return 0;
}

[BZOJ3864]Hero meet devil(状压dp)

题意:给一个长度 这个题让我想起了之前做过的一个数位dp,问有多少个数的数字组成的最长上升子序列长度为x。那个题中显然最长上升子序列不超过10,我们用状态压缩来模拟那个做lis时的栈即可。 这个题...
  • u011542204
  • u011542204
  • 2016年06月14日 20:16
  • 502

BZOJ3864: Hero meet devil DP套DP

题意:给出字符串S,对于每一个i,问有多少个长度为m的字符串与S的最长公共子序列长度为i |S|...
  • Mima_Reincarnation
  • Mima_Reincarnation
  • 2017年04月11日 16:36
  • 234

BZOJ 3864 Hero meet devil DP套DP

题目大意:给定一个长度为n(n≤15)n(n\leq 15)的基因序列SS,求对于每个i(0≤i≤n)i(0\leq i\leq n)有多少长度为m(m≤1000)m(m\leq1000)的基因串TT...
  • PoPoQQQ
  • PoPoQQQ
  • 2015年07月10日 09:30
  • 2480

[BZOJ 3864][HDU 4899]Hero meet devil(DP套DP)

题目链接:(1)http://www.lydsy.com/JudgeOnline/problem.php?id=3864 (2)http://acm.hdu.edu.cn/showproblem.p...
  • qpswwww
  • qpswwww
  • 2015年02月19日 12:17
  • 1796

BZOJ3864 Hero meet devil

上午考试的时候AK了,看代码还挺短的,于是学习了一下DP套DP,感觉挺傻逼的 考虑求LCS那个DP,我们发现对于固定的i和任意的j,f[i][j]最多只能和f[i-1][j]有关,不可能和f[i-2]...
  • neither_nor
  • neither_nor
  • 2017年06月01日 20:50
  • 427

BZOJ3864: Hero meet devil

Description There is an old country and the king fell in love with a devil. The devil always asks...
  • wxh010910
  • wxh010910
  • 2017年01月10日 21:12
  • 282

[BZOJ 3864][HDU 4899]Hero meet devil(DP套DP)

题意 给你一个只由AGCT组成的字符串S(|S|≤15),对于每个1≤i≤|S| 询问有多少个只由AGCT组成的长度为m(1≤m≤1000)的字符串T,使得LCS(S,T)=i。 |S|...
  • DraZxlNDdt
  • DraZxlNDdt
  • 2017年03月08日 10:12
  • 271

BZOJ3864: Hero meet devil

这题吼厉害呀,Orz cls 假设我们知道了最终串T,考虑求T和S求LCS的过程,f[i][j]表示串T的前i位和串S的前j位的LCS最长是多少,有f[i][j]=max(f[i−1][j],f[i...
  • L_0_Forever_LF
  • L_0_Forever_LF
  • 2018年01月13日 15:30
  • 98

[DP套DP] BZOJ 3864 Hero meet devil

我们令fi,jf_{i,j}表示TiT_i和SjS_j的LCS 然后我们发现 fi,j−fi,j−1∈[0,1]f_{i,j}-f_{i,j-1} \in [0,1] 这个东西可以状压 预处理所有...
  • u014609452
  • u014609452
  • 2017年05月31日 20:20
  • 172

BZOJ 3864: Hero meet devil【dp套dp

把LCS当成子串 看样例看了一年 这几天特别颓废啊【滑稽 …先考虑LCS的求法,以及给出的字符串长度,显然是需要状压的 对于求LCS的时候用的数组 dp[i][j]        把d...
  • Flaze_
  • Flaze_
  • 2016年12月25日 21:36
  • 298
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:BZOJ 3864 Hero meet devil DP套DP
举报原因:
原因补充:

(最多只允许输入30个字)