• HDU 4057:Rescue the Rabbit(AC自动机+状压DP)***


    http://acm.hdu.edu.cn/showproblem.php?pid=4057

    题意:给出n个子串,串只包含‘A’,'C','G','T'四种字符,你现在需要构造出一个长度为l的串,如果这个串里面包含了某个子串,那么答案就会+val[i](如果这个串被使用过了,就不会再有贡献了),要使得构造出来的串的答案最大,问是多少。

    思路:只能想到是AC自动机的题目,然后乱搞出一个错误的方法,没想到是这样的操作。

    n只有10,因此才1024,开一个dp[l][sz][st]的数组,l代表当前的字符串长度,sz代表当前遍历的结点,st代表当前的状态(二进制表示使用了哪些字符串),这里的长度用滚动数组优化。

    方程:dp[now][nxt[j][x]][k|val[nxt[j][x]]] = dp[pre][j][k]; (当且仅当dp[pre][j][k]状态可取)

    nxt[j][x]代表j结点的下一个状态,val[now]代表now这个结点是哪个字符串的终点,因此k|val[nxt[j][x]]就是当前拥有的字符串的状态+下一个结点拥有的字符串的状态。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <queue>
     5 using namespace std;
     6 #define N 1010
     7 #define INF 0x3f3f3f3f
     8 int nxt[N][4], fail[N], val[N], rt, sz, n, l, num[11];
     9 bool dp[2][N][(1<<10)+10];
    10 char s[105];
    11 int newnode() {
    12     for(int i = 0; i < 4; i++) nxt[sz][i] = -1;
    13     val[sz++] = 0;
    14     return sz - 1;
    15 }
    16 void init() {
    17     sz = 0; rt = newnode();
    18 }
    19 int Turn(char c) {
    20     if(c == 'A') return 0;
    21     if(c == 'C') return 1;
    22     if(c == 'G') return 2;
    23     return 3;
    24 }
    25 void Insert(int id) {
    26     int len = strlen(s);
    27     int now = rt;
    28     for(int i = 0; i < len; i++) {
    29         int c = Turn(s[i]);
    30         if(nxt[now][c] == -1) nxt[now][c] = newnode();
    31         now = nxt[now][c];
    32     }
    33     val[now] |= (1 << id);
    34 }
    35 void Build() {
    36     queue<int> que;
    37     while(!que.empty()) que.pop();
    38     fail[rt] = rt;
    39     for(int i = 0; i < 4; i++) {
    40         if(nxt[rt][i] == -1) nxt[rt][i] = rt;
    41         else fail[nxt[rt][i]] = rt, que.push(nxt[rt][i]);
    42     }
    43     while(!que.empty()) {
    44         int now = que.front(); que.pop();
    45         val[now] |= val[fail[now]]; // 如果fail指向的结点是有状态的,应该加上!!!
    46         for(int i = 0; i < 4; i++) {
    47             if(nxt[now][i] == -1) nxt[now][i] = nxt[fail[now]][i];
    48             else fail[nxt[now][i]] = nxt[fail[now]][i], que.push(nxt[now][i]);
    49         }
    50     }
    51 }
    52 void Solve() {
    53     int pre = 0, now = 1;
    54     memset(dp, 0, sizeof(dp));
    55     dp[pre][0][0] = 1;
    56     for(int i = 0; i < l; i++) {
    57         memset(dp[now], 0, sizeof(dp[now]));
    58         for(int j = 0; j < sz; j++) {
    59             for(int k = 0; k < (1 << n); k++) {
    60                 if(!dp[pre][j][k]) continue;
    61                 for(int x = 0; x < 4; x++) {
    62                     dp[now][nxt[j][x]][k|val[nxt[j][x]]] = dp[pre][j][k]; // 哪些状态可以取
    63                     // nxt[j][x] 下一个结点
    64                     // k | val[nxt[j][x]] 当前状态加上下一个结点有的状态
    65                 }
    66             }
    67         }
    68         swap(now, pre);
    69     }
    70     int ans = -INF, res; now = l % 2;
    71     for(int i = 0; i < sz; i++) {
    72         for(int j = 0; j < (1 << n); j++) {
    73             if(!dp[now][i][j]) continue;
    74             res = 0;
    75             for(int k = 0; k < n; k++)
    76                 if(j & (1 << k)) res += num[k];
    77             ans = ans > res ? ans : res;
    78         }
    79     }
    80     if(ans >= 0) printf("%d
    ", ans);
    81     else puts("No Rabbit after 2012!");
    82 }
    83 
    84 int main() {
    85     while(~scanf("%d%d", &n, &l)) {
    86         init();
    87         for(int i = 0; i < n; i++) scanf("%s %d", s, &num[i]), Insert(i);
    88         Build();
    89         Solve();
    90     }
    91     return 0;
    92 }
    93 
    94 /*
    95 3 2
    96 A -1
    97 G -1
    98 C -1
    99 */
  • 相关阅读:
    linux下启动和关闭网卡命令及DHCP上网
    python 编码问题
    paddlepaddle
    Convolutional Neural Network Architectures for Matching Natural Language Sentences
    deep learning RNN
    Learning Structured Representation for Text Classification via Reinforcement Learning 学习笔记
    Python IO密集型任务、计算密集型任务,以及多线程、多进程
    EM 算法最好的解释
    tensorflow 调参过程
    tensorflow 学习纪录(持续更新)
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6828651.html
Copyright © 2020-2023  润新知