zoukankan      html  css  js  c++  java
  • HDU 2825 位压缩

    题意,,,给你 M 个字符去组成密码,密码的长度规定为 N,所组成的密码要求至少 含有 M 个字符里面的 K 个,字符可能包含,不能重复计算;

    这个    有点难度;因为  M 很小,所以,可以用二进制来做,当然  内存可能会爆,如果不注意好的话; 上题是要不包含字符,而这题是要求包含字符,那么对应的每一个状态是不是又多了一维变量,每个状态包含了多少个字符,从 1~k --》

    #include<iostream>
    #include<stdio.h>
    #include<cstring>
    #include<algorithm>
    #define mod 20090717
    using namespace std;
    
    struct date 
    {
        date *next[26],*fail;
        int in,cnt;
    }tree[1221],*que[1221],*root;
    int N,M,P,tail,head,total;
    char dir[20][20];
    
    date *creat_node( )
    {
        for( int i = 0; i < 26; i++ )
        tree[total].next[i] = NULL;
        tree[total].fail    = NULL;
        tree[total].in = total;
        tree[total].cnt = 0;
        return &tree[total++];
    }
    
    void inint( )
    {
        tail = head = total = 0;
        root = creat_node();
        root->fail = root;
    }
    
    void insert( char *word,int i )
    {
        date *temp = root;
        while( *word )
        {
            int k = *word - 'a';
            if( temp->next[k] == NULL )
                temp->next[k] = creat_node();
            temp = temp->next[k];
            word++;
        }
        temp->cnt |= (1<<i);
    }
    
    void build_AC( )
    {
        que[tail++] = root;
        while( tail > head )
        {
            date *temp = que[head++];
            for( int i = 0; i < 26; i++ )
            if( temp->next[i] )
            {
                if( temp == root ) temp->next[i]->fail = root;
                else               temp->next[i]->fail = temp->fail->next[i];
                temp->next[i]->cnt = temp->next[i]->cnt|temp->fail->next[i]->cnt|temp->cnt;
                que[tail++] = temp->next[i];
            }
            else 
            {
                if( temp == root ) temp->next[i] = root;
                else               temp->next[i] = temp->fail->next[i];
            }
        }
    }
    
    int map[1500];
    void work( )
    {
        for( int i = 0; i <= 1500; i++ )
        map[i] = map[i>>1] + (i&1);
    }
    
    int  dp[27][121][1500];
    void DP( )
    {
         int i,j,k,l,pos,res;
         pos = (1<<M );
         for (i = 0; i <= N; ++i)  
         for (j = 0; j < total; ++j)  
         for (k = 0; k < (1<<M); ++k)  
             dp[i][j][k] = 0;  
         dp[0][0][0] = 1;
         for( i = 1; i <= N;   i++ )
         for( j = 0; j <total; j++ )
         for( k = 0; k < pos;  k++ )
         {
               if( dp[i-1][j][k] == 0 ) continue;
            int a = dp[i-1][j][k];
            for( l = 0; l <  26;  l++ )
            {
              int b = tree[j].next[l]->in;
              int c = tree[j].next[l]->cnt;
              dp[i][b][k|c] = ( a + dp[i][b][k|c] )%mod;
            }
         }
         res = 0; 
         for( i = 0; i <  total; i++ )
         for( j = 0; j <  pos; j++ )
         if( map[j] >= P )
             res = ( res + dp[N][i][j] )%mod;
         printf("%d\n",res);
    }
    
    
    int main( )
    {
         work();
         while( scanf("%d%d%d",&N,&M,&P) != EOF )
         {
             if( N+M+P == 0 )break;
             inint();
             for( int i = 0; i < M; i++ )
             scanf("%s",&dir[i]),insert( dir[i],i );
             build_AC( );
             DP( );
         }
         return 0;
    }
  • 相关阅读:
    redis(4)
    基于参数shared_pool_reserved_size进一步理解共享池shared pool原理
    如何诊断oracle数据库运行缓慢或hang住的问题
    freqently asked questions for oracle database server patching
    cpu 过高检查
    DB2和Oracle区别
    RMAN迁移数据库到ASM(一)创建ASM磁盘组
    Oracle 12C 块修改跟踪(Block chage tracking) 功能
    Oracle 12c RMAN备份与恢复实验
    Oracle ASM磁盘组迁移指导手册
  • 原文地址:https://www.cnblogs.com/wulangzhou/p/3016746.html
Copyright © 2011-2022 走看看