zoukankan      html  css  js  c++  java
  • hdu 4057 Rescue the Rabbit

    题意

      给出n(n<=10)个串,每个串有个权值,然后让你构造一个长度为l(l<=100)的串,如果他包含给出的串就得到相应的权值,求可能得到的最大权值

    解法

      AC自动机+DP,很显然要建立自动机,然后在上面跑,如果不要求每个串的权值只能获取一次,那么直接跑来跑去的就行,但是因为只能取一次,串很少,可以状态压缩DP,dp[i][j][k]记录前i个字符走到j状态并且已经获得的串状态为k时的最优解。需要滚动数组优化空间--

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<queue>
      4 #include<algorithm>
      5 using namespace std;
      6 const int N = 1010;
      7 const int inf = ~0u>>2;
      8 int hash[129];
      9 struct node{
     10     node *ch[4],*fail;
     11     int mask;
     12     void clear(){
     13         for(int i = 0;i < 4;i++)ch[i] = NULL;fail = NULL;
     14         mask = 0;
     15     }
     16 };
     17 node stk[N*10];
     18 bool dp[2][N][1024];
     19 int score[1024];
     20 struct Trie{
     21     node *root;int top;
     22     node* newnode(){
     23         node *p = &stk[top++];
     24         p -> clear();
     25         return p;
     26     }
     27     void init(){
     28         top = 0;
     29         root = newnode();
     30     }
     31     void insert(char *s,int number){
     32         node *p = root;int len = strlen(s);
     33         for(int i = 0;i < len;i++){
     34             int id = hash[s[i]];
     35             if(p -> ch[id] == NULL)
     36                 p -> ch[id] = newnode();
     37             p = p -> ch[id];
     38         }
     39         p -> mask |= 1<<number;
     40     }
     41     void build(){
     42         queue<node*> Q;
     43         root -> fail = root;
     44         for(int i = 0;i < 4;i++)
     45             if(root -> ch[i] == NULL)
     46                 root -> ch[i] = root;
     47             else{
     48                 Q.push(root -> ch[i]);
     49                 root -> ch[i] -> fail = root;
     50             }
     51         while(!Q.empty()){
     52             node *p = Q.front();Q.pop();
     53             for(int i = 0;i < 4;i++)
     54                 if(p -> ch[i] == NULL)
     55                     p -> ch[i] = p -> fail -> ch[i];
     56                 else{
     57                     Q.push(p -> ch[i]);
     58                     p -> ch[i] -> fail = p -> fail -> ch[i];
     59                     p -> ch[i] -> mask |= p -> ch[i] -> fail -> mask;
     60                 }
     61         }
     62     }
     63     int solve(int len,int number){
     64         memset(dp,0,sizeof(dp));
     65         dp[0][0][0] = true;
     66         for(int i = 1;i <= len;i++){
     67             memset(dp[i&1],0,sizeof(dp[i&1]));
     68             for(int j = 0;j < top;j++){
     69                 node *cur = &stk[j];
     70                 for(int st = 0;st < 1<<number;st++){
     71                     if(dp[(i+1)&1][j][st]){
     72                         for(int k = 0;k < 4;k++){
     73                             node *next = cur -> ch[k];
     74                             dp[i&1][next - stk][st | next -> mask] = 1;
     75                         }
     76                     }
     77                 }
     78             }
     79         }
     80         int ans = -inf;
     81         for(int i = 0;i < top;i++)
     82             for(int j = 0;j < 1<<number;j++)
     83                 if(dp[len&1][i][j]){
     84                     ans = max(ans,score[j]);
     85                 }
     86         return ans;
     87     }
     88 };
     89 Trie AC;
     90 char s[N];
     91 int w[11];
     92 int main(){
     93     hash['A'] = 0;hash['C'] = 1;hash['G'] = 2;hash['T'] = 3;
     94     int n,l;
     95     int cas = 1;
     96     while(~scanf("%d%d",&n,&l)){
     97         AC.init();
     98         for(int i = 0;i < n;i++){
     99             scanf("%s%d",s,&w[i]);
    100             AC.insert(s,i);
    101         }
    102         for(int i = 0;i < 1<<n ;i++){
    103             score[i] = 0;
    104             for(int j = 0;j < n;j++)
    105                 if(i&(1<<j))score[i] += w[j];
    106         }
    107         AC.build();
    108         int ans = AC.solve(l,n);
    109         //printf("Case %d
    ",cas++);
    110         if(ans < 0)puts("No Rabbit after 2012!");
    111         else printf("%d
    ",ans);
    112     }
    113     return 0;
    114 }
  • 相关阅读:
    什么是动态链接库
    <<TCP/IP高效编程>>读书笔记
    C++ 函数
    我的vim配置
    FastReport4.6程序员手册_翻译
    DUnit研究初步
    ADO BUG之'无法为更新定位行....' 解决之道
    极限编程的集成测试工具Dunit
    总结
    项目管理检查清单项目启动
  • 原文地址:https://www.cnblogs.com/silver-bullet/p/3254129.html
Copyright © 2011-2022 走看看