zoukankan      html  css  js  c++  java
  • BZOJ3864 Hero meet devil

    题面

    BZOJ权限题

    HDU

    vjudge

    题解

    $dp$套$dp$。。。

    根据$lcs$的转移:

    $$ lcs[i][j]=max egin{cases} lcs[i-1][j-1]+1 & (t[i] = s[j]) \ max(lcs[i-1][j],lcs[i][j-1]) & (t[i] eq s[j]) end{cases} $$

    于是$lcs[i][j] - lcs[i][j - 1] leq 1$

    因为$|S|leq 15$我们可以状压差分后的$lcs[i]$数组。

    设$f[i][S]$表示$dp$到第$i$位,$lcs[i]$为$S$的方案数,

    然后枚举这个位置选$ ext{A/G/C/T}$的哪一个。

    设$trans[S][ ext{A/G/C/T}]$为$lcs$为$S$时加一个字母后的$lcs$的状态

    这个可以预处理出来。

    于是转移方程为:

    $$ f[i][trans[S][ ext{A/G/C/T}]] ext{+=}f[i-1][S] $$

    边界$f[0][0]=1$

    代码

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #define RG register
    #define file(x) freopen(#x".in", "r", stdin);freopen(#x".out", "w", stdout);
    #define clear(x, y) memset(x, y, sizeof(x))
    #define pcnt __builtin_popcount
    
    const int maxn(1001), Mod(1e9 + 7), LEN(15);
    char s[LEN + 1], S_now[] = "AGCT";
    int a[LEN + 1], f[maxn][(1 << LEN) | 2], T, LIM, ans[maxn];
    int trans[(1 << LEN) | 2][5], n, len, tmp[2][LEN + 1];
    
    int Calc(int S, int c)
    {
    	int ans = 0; clear(tmp, 0);
    	for(RG int i = 0; i < n; i++) tmp[0][i + 1] = tmp[0][i] + ((S >> i) & 1);
    	for(RG int i = 1; i <= n; i++)
    	{
    		int max = 0; if(a[i] == c) max = tmp[0][i - 1] + 1;
    		max = std::max(std::max(max, tmp[0][i]), tmp[1][i - 1]);
    		tmp[1][i] = max;
    	}
    	for(RG int i = 0; i < n; i++) ans += (1 << i) * (tmp[1][i + 1] - tmp[1][i]);
    	return ans;
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
    	file(cpp);
    #endif
    	scanf("%d", &T);
    	while(T--)
    	{
    		clear(f, 0); clear(ans, 0);
    		scanf("%s", s + 1);
    		n = strlen(s + 1); LIM = (1 << n);
    		for(RG int i = 1; i <= n; i++)
    			for(RG int j = 0; j < 4; j++)
    				if(s[i] == S_now[j]) { a[i] = j + 1; break; }
    		scanf("%d", &len); f[0][0] = 1;
    		for(RG int i = 0; i < LIM; i++)
    			for(RG int j = 1; j <= 4; j++) trans[i][j] = Calc(i, j);
    		for(RG int i = 1; i <= len; i++)
    			for(RG int S = 0; S < LIM; S++)
    				for(RG int k = 1; k <= 4; k++)
    					f[i][trans[S][k]] = (f[i][trans[S][k]] + f[i - 1][S]) % Mod;
    		for(RG int S = 0; S < LIM; S++)
    			ans[pcnt(S)] = (ans[pcnt(S)] + f[len][S]) % Mod;
    		for(RG int i = 0; i <= n; i++) printf("%d
    ", ans[i]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    textare限制拖动;提示文字(点击消失,不输入恢复提示信息)
    JSON整理
    Bootstrap-模态框 modal.js
    input自动填入密码以后变成白色和黄色的解决办法
    Bootstrap-按钮篇btn
    jquery关于Select元素的操作
    数据库外键
    数据库一些操作
    爬虫日记-代理
    爬虫日记-模拟登录cookie操作
  • 原文地址:https://www.cnblogs.com/cj-xxz/p/10220486.html
Copyright © 2011-2022 走看看