码迷,mamicode.com
首页 > 其他好文 > 详细

[hdu 4899]14年多校第四场C Hero meet devil 状压DP

时间:2014-08-03 18:10:05      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:dp

Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 122    Accepted Submission(s): 49

Problem Description
There is an old country and the king fell in love with a devil. The devil always asks the king to do some crazy things. Although the king used to be wise and beloved by his people. Now he is just like a boy in love and can’t refuse any request from the devil. Also, this devil is looking like a very cute Loli.

After the ring has been destroyed, the devil doesn‘t feel angry, and she is attracted by z*p‘s wisdom and handsomeness. So she wants to find z*p out.

But what she only knows is one part of z*p‘s DNA sequence S leaving on the broken ring.

Let us denote one man‘s DNA sequence as a string consist of letters from ACGT. The similarity of two string S and T is the maximum common subsequence of them, denote by LCS(S,T).

After some days, the devil finds that. The kingdom‘s people‘s DNA sequence is pairwise different, and each is of length m. And there are 4^m people in the kingdom.
Then the devil wants to know, for each 0 <= i <= |S|, how many people in this kingdom having DNA sequence T such that LCS(S,T) = i.
You only to tell her the result modulo 10^9+7.
 
Input
The first line contains an integer T, denoting the number of the test cases.
For each test case, the first line contains a string S. the second line contains an integer m.


T<=5
|S|<=15. m<= 1000.
 
Output
For each case, output the results for i=0,1,...,|S|, each on a single line.
 
Sample Input
1
GTC
10
 
Sample Output
1
22783
528340
497452

Author
WJMZBMR
 
Source

2014 Multi-University Training Contest 4


题目大意

给定DNA序列长度m和一个DNA(每单位DNA有AGCT 4种可能)片段,求所有和所给序列最长公共子串长度为0~len的DNA数量


解题思路

在开题的时候以为是数论+组合数学,思路越想越偏……

后来CLJ给出超简要的题解……

听别人的一种按位压缩的思路,就是枚举到该位置之时LCS所对应的位置,若一一对应则该位为1,否则为0

而当我们要处理新的单位DNA时就有一个变换LCS对应的会改变。

则我们枚举所有可能的匹配位置并枚举下一位,算出下一个状态对应的LCS所在位置,按位压缩。


当我们处理长度为m的DNA是就可以直接带入了。

因为m<=1000dp状态采用滚动数组存储


code:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <ctime>
#include <cctype>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <set>

#define sqr(x) ((x)*(x))
#define LL long long 
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define eps 1e-10
#define mod 1000000007
using namespace std;
int bitc(int x)//计算LCS长度
{
    int ans=0;
    while (x)
    {
        ans+=x%2;
        x/=2;
    }
    return ans;
}
int dp[2][(1<<16)+10];
int to[(1<<16)+10][4];
int bt[20];
int go[20];
int ma[20];
int t[20];
char l[5]="ACGT";
char s[100];
int main()
{
    int T,n,m;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%s",s);
        n=strlen(s);
        scanf("%d",&m);
        for (int i=0;i<(1<<(n+1));i++)
        {
            bt[0]=0;
            // printf("%d   ",i );
            for (int j = 1; j <= n; ++j)
            {
                if ((1<<(j-1))&i) bt[j]=bt[j-1]+1;
                else bt[j]=bt[j-1];
            }
            for (int p = 0; p < 4; ++p)
            {
                go[0]=0;
                for (int j = 1; j <= n; ++j)
                {
                    if (l[p]==s[j-1]) go[j]=bt[j-1]+1;
                    else go[j]=max(go[j-1],bt[j]);
                }
                int tmp=0;
                for (int j = 1; j <= n; ++j)
                if (go[j]-go[j-1])
                {
                    tmp|=1<<(j-1);
                }
                to[i][p]=tmp;
                // printf("%d|",tmp );
            }
            // puts("");
        }
        memset(dp[0],0,sizeof dp[0]);
        dp[0][0]=1;
        for (int i=1;i<=m;i++)
        {
            memset(dp[i&1],0,sizeof dp[i&1]);
            for (int j=0;j<(1<<(n+1));j++)
            {
                if (dp[i&1^1][j]==0) continue;
                for (int p=0;p<4;p++)
                {
                    dp[i&1][to[j][p]]+=dp[i&1^1][j];
                    dp[i&1][to[j][p]]%=mod;
                }
            }

            // for (int j=0;j<(1<<(n+1));j++)
            //     printf("%d ",dp[i&1][j]);
            // puts("");
        }
        memset(t,0,sizeof t);
        for (int j=0;j<(1<<(n+1));j++)
            {
                t[bitc(j)]+=dp[m&1][j];
                t[bitc(j)]%=mod;
            }
        for (int i=0;i<=n;i++)
            printf("%d\n",t[i]);
    }
    return 0;
}
/*
1
GTC
10 


1
22783
528340
497452
*/


[hdu 4899]14年多校第四场C Hero meet devil 状压DP,布布扣,bubuko.com

[hdu 4899]14年多校第四场C Hero meet devil 状压DP

标签:dp

原文地址:http://blog.csdn.net/ahm001/article/details/38358349

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!