zoukankan      html  css  js  c++  java
  • HDU3341AC自动机+dp

    题意:N个子串,每个串价值为1,给你一个长串S,求重排后最大的价值(可重叠);

    明白题意后,很裸的自动机+DP,建完自动机状态表示成dp[2][500][20][20][20],把其中3个必然小于20的元素来DP,然后TLE,40*500*20*20*20,有30组case,必然TLE;

    View Code
      1 /*
      2 学习一:一种压缩方式,类似于进制表示,每个元素的个数确定后
      3 num[],那么bas[0]=1,bas[1]=bas[i-1]*(num[i-1]+1);
      4 例如num[]={2,1,3,2};bas[]={1,3,6,24};
      5 编码 incode() ret+=num[i]*bas[i];
      6 然后就是解码 decode();
      7 这样把20^3*40的空间压缩成11^4的空间;
      8 但是还是TLE;40*500*4*11^4*30;
      9 我们发现状态的转移都是从长度为n-1转移到n;
     10 而长度为n-1的编码一定是小于长度为n的编码的;
     11 类似于1100->1101或1110数值都是变大的;
     12 所以直接从编码小的转移到编码大的就可以了,
     13 500*11^4*4*30  AC;
     14 */
     15 //18:34
     16 #include<cstdio>
     17 #include<cstring>
     18 #include<cstdlib>
     19 #include<iostream>
     20 #include<algorithm>
     21 #include<cmath>
     22 #include<queue>
     23 #include<map>
     24 using namespace std;
     25 const int N=500+10;
     26 const int SZ=4;
     27 int idx(char s){
     28     if (s=='A') return 0;
     29     if (s=='G') return 1;
     30     if (s=='T') return 2;
     31     return 3;
     32 }
     33 struct AC{
     34     int ch[N][SZ];
     35     int sz,f[N],match[N];
     36     queue<int> q;
     37     void init(){
     38         sz=1;memset(match,0,sizeof(match));
     39         memset(ch[0],0,sizeof(ch[0]));
     40     }
     41     void insert(char *s){
     42         int m=strlen(s),rt=0;
     43         for (int i=0;i<m;i++){
     44             int c=idx(s[i]);
     45             if (ch[rt][c]==0){
     46                 ch[rt][c]=sz;
     47                 memset(ch[sz],0,sizeof(ch[sz]));
     48                 sz++;
     49             }
     50             rt=ch[rt][c];
     51         }
     52         match[rt]+=1;
     53     }
     54     void getfail(){
     55         while (!q.empty()) q.pop();
     56         for (int i=0;i<SZ;i++){
     57             int c=ch[0][i];
     58             if (c){ f[c]=0;q.push(c); }
     59         }
     60         while(!q.empty()){
     61             int u=q.front();q.pop();
     62             for (int i=0;i<SZ;i++){
     63                 int r=ch[u][i];
     64                 if(!r){
     65                     ch[u][i]=ch[f[u]][i];
     66                 }else {
     67                     q.push(r);
     68                     int v=f[u];
     69                     f[r]=ch[v][i];
     70                     match[r]+=match[f[r]];
     71                 }
     72             }
     73         }
     74     }
     75     void find(){
     76         cout<<"----------- "<<endl;
     77         for (int i=0;i<sz;i++){
     78             if (match[i]) cout<<i<<" "<<match[i]<<endl;
     79         }
     80         cout<<"+++++++++++ "<<endl;
     81     }
     82 }H;
     83 /////////////////////AC自动机部分///////////////////////
     84 char T[50];
     85 int up[10];
     86 int bas[10];
     87 void init(){
     88     scanf("%s",T);
     89     memset(up,0,sizeof(up));
     90     for (int i=0;T[i];i++){
     91         int c=idx(T[i]);
     92         up[c]++;
     93     }
     94     bas[0]=1;
     95     for (int i=1;i<=4;i++){
     96         bas[i]=bas[i-1]*(up[i-1]+1);
     97     }
     98   /*  cout<<"*** "<<endl;
     99     for (int i=0;i<=4;i++){
    100         cout<<bas[i]<<" ";
    101     }cout<<endl;
    102     cout<<"/// "<<endl;
    103 */
    104 }
    105 int dp[15000][N];
    106 void decode(int *num,int k){
    107     for (int i=3;i>=0;i--){
    108         num[i]=k/bas[i];
    109         k=k%bas[i];
    110     }
    111 }
    112 void Max(int &x,int y){
    113     if (x==-1) {
    114         x=y; 
    115     }else {
    116         x=max(x,y);
    117     }
    118 }
    119 void DP(){
    120     memset(dp,-1,sizeof(dp));
    121     dp[0][0]=0;
    122     int num[10];
    123     for (int i=0;i<bas[4];i++){
    124        decode(num,i);
    125        for (int j=0;j<H.sz;j++){
    126             if (dp[i][j]!=-1){
    127                 for (int k=0;k<SZ;k++){
    128                     int c=H.ch[j][k];
    129                     if (num[k]<up[k]){
    130                         int t=i+bas[k];
    131                         Max(dp[t][c],dp[i][j]+H.match[c]);
    132                     }
    133                 }
    134             }
    135         }
    136     }
    137 
    138     int ret=-1,all=bas[4]-1;
    139     for (int i=0;i<H.sz;i++){
    140         if (dp[all][i]!=-1) Max(ret,dp[all][i]);
    141     }
    142     printf("%d\n",ret);
    143 }
    144 int n;
    145 char p[15];
    146 int main(){
    147     int cas=0;
    148     while (~scanf("%d",&n),n){
    149         H.init();
    150         for (int i=0;i<n;i++){
    151             scanf("%s",p);
    152             H.insert(p);
    153         }
    154         H.getfail();
    155         //
    156        // H.find();
    157         //
    158         init();
    159         printf("Case %d: ",++cas);
    160         DP();
    161     }
    162     return 0;
    163 }
  • 相关阅读:
    Thinkphp M方法出错,D方法却可以
    Composer项目安装依赖包
    wamp httpd-vhosts.conf
    博客园报错 Mixed Content: The page at 'https://i.cnblogs.com/EditPosts.aspx?opt=1' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://upload.cnblogs.com/imageuploa
    Thinkphp js、css压缩类minify
    Thinkphp 不足之处
    Thinkphp 调试方法
    Lavavel 程序报错 MassAssignmentException in Model.php line 452: _token
    Laravel 安装mysql、表增加模拟数据、生成控制器
    Laravel 安装登录模块
  • 原文地址:https://www.cnblogs.com/Rlemon/p/3008830.html
Copyright © 2011-2022 走看看