BZOJ3864: Hero meet devil(dp套dp)
2018-06-17 20:42:48来源:未知 阅读 ()
Submit: 397 Solved: 206
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
GTC
10
Sample Output
22783
528340
497452
HINT
Source
首先想一下LCS的转移方程
$$lcs[i][j]=max \begin{cases} lcs[i-1][j-1]+1 & \text{if t[i]=s[j]} \\ lcs[i-1][j] \\ lcs[i][j-1] \end{cases}$$
这样的话,当$i$确定是,$lcs[i][j]$和$lcs[i][j-1]$最多相差$1$
且题目中说$|S|<= 15$,因此我们考虑把差分后的lcs数组状压起来
那么如何统计答案呢?
设$f[i][sta]$表示在第$i$个位置,此时lcs的状态为$sta$的方案数,
然后我们枚举一下这个位置选ACGT中的哪个
设$trans[sta'][A/C/G/T]$为在$sta$状态表示的lcs后加了ACGT中的一个后的状态,这个很显然可以预处理得到
那么转移方程为
$$f[i][ trans[sta][k] ] += f[i - 1][sta] $$
$$f[0][0] = 1$$
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 1001, mod = 1e9 + 7; char S[16], SS[] = {"ACGT"}; int a[16], f[MAXN][(1 << 15) + 2], trans[(1 << 15) + 2][5], N, Len, limit, ans[111]; int tmp[2][16]; int solve(int sta, int ch) { int ret = 0; memset(tmp, 0, sizeof(tmp)); for(int i = 0; i < N; i++) tmp[0][i + 1] = tmp[0][i] + ((sta >> i) & 1 ); for(int i = 1; i <= N; i++) { int mx = 0; if(a[i] == ch) mx = tmp[0][i - 1] + 1; mx = max( max(mx, tmp[0][i]), tmp[1][i-1]); tmp[1][i] = mx; } for(int i = 0; i < N; i++) ret += (1 << i) * (tmp[1][i + 1] - tmp[1][i]); return ret; } int main() { #ifdef WIN32 freopen("a.in", "r", stdin); #endif int QWQ;scanf("%d", &QWQ); while(QWQ--) { memset(f, 0, sizeof(f));memset(ans, 0, sizeof(ans)); scanf("%s", S + 1); N = strlen(S + 1); limit = (1 << N) - 1; for(int i = 1; i <= N; i++) for(int j = 0; j < 4; j++) if(S[i] == SS[j]){a[i] = j + 1;break;} scanf("%d", &Len); f[0][0] = 1; for(int sta = 0; sta <= limit; sta++) for(int j = 1; j <= 4; j++) trans[sta][j] = solve(sta, j); for(int i = 1; i <= Len; i++) for(int sta = 0; sta <= limit; sta++) for(int k = 1; k <= 4; k++) f[i][ trans[sta][k] ] = (f[i][ trans[sta][k] ] + f[i - 1][sta]) % mod; for(int sta = 0; sta <= limit; sta++) ans[__builtin_popcount(sta)] = (ans[__builtin_popcount(sta)] + f[Len][sta]) % mod; //这个函数是算出sta中1的个数 for(int i = 0; i <= N; i++) printf("%d\n", ans[i] % mod); } return 0; }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- BZOJ1191: [HNOI2006]超级英雄Hero(二分图匹配) 2018-07-09
- 【入门】匈牙利算法+HNOI2006 hero超级英雄 2018-06-17
- HDU_5521_Meeting 2018-06-17
- meetnow的概念和使用_autocad教程 2008-02-23
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash