• HUNAN 11569 Just Another Knapsack Problem(AC自动机+dp)


    http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11569&courseid=0

    给出目标串,每个子串和对应的权值,然后要从子串中匹配出目标串并且权值最大.匹配的位置不能重复.

    dp[i]为匹配到i这个位置时的最大价值,那么dp[i]=max(dp[i],dp[i-len[j]]+val[j]);

    每次找到的匹配的子串在目标串的位置,然后动态转移。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cmath>
      4 #include <vector>
      5 #include <cstring>
      6 #include <algorithm>
      7 #include <string>
      8 #include <set>
      9 #include <functional>
     10 #include <numeric>
     11 #include <sstream>
     12 #include <stack>
     13 #include <map>
     14 #include <queue>
     15 
     16 #define CL(arr, val)    memset(arr, val, sizeof(arr))
     17 
     18 #define ll long long
     19 #define inf 0x7f7f7f7f
     20 #define lc l,m,rt<<1
     21 #define rc m + 1,r,rt<<1|1
     22 #define pi acos(-1.0)
     23 
     24 #define L(x)    (x) << 1
     25 #define R(x)    (x) << 1 | 1
     26 #define MID(l, r)   (l + r) >> 1
     27 #define Min(x, y)   (x) < (y) ? (x) : (y)
     28 #define Max(x, y)   (x) < (y) ? (y) : (x)
     29 #define E(x)        (1 << (x))
     30 #define iabs(x)     (x) < 0 ? -(x) : (x)
     31 #define OUT(x)  printf("%I64d
    ", x)
     32 #define lowbit(x)   (x)&(-x)
     33 #define Read()  freopen("a.txt", "r", stdin)
     34 #define Write() freopen("dout.txt", "w", stdout);
     35 
     36 
     37 #define Nn 510007
     38 #define Mc 26
     39 
     40 using namespace std;
     41 
     42 class Acautomaton
     43 {
     44     private:
     45 
     46     int chd[Nn][Mc];
     47     int fail[Nn];
     48     int ID[Mc];
     49     int val[Nn];
     50     int Q[Nn];
     51     int sz;
     52     int len[Nn];
     53 
     54     public:
     55     int dp[101000];
     56     void Init()
     57     {
     58         fail[0] = 0;
     59         for (int i = 0; i < Mc; ++i)
     60         {
     61             ID[i] = i;
     62         }
     63     }
     64     void Reset()
     65     {
     66         CL(chd[0],0);
     67         sz = 1;
     68     }
     69     int idx(char c) {return c-'a';}
     70     void insert(char *s,int key)
     71     {
     72         int p = 0;
     73         for (; *s; s++)
     74         {
     75             int k = ID[*s - 'a'];
     76             if (!chd[p][k])
     77             {
     78                 CL(chd[sz],0);
     79                 val[sz] = 0;
     80                 len[sz]=0;
     81                 chd[p][k] = sz++;
     82             }
     83             len[chd[p][k]]=len[p]+1;
     84             p = chd[p][k];
     85         }
     86         val[p] =max(val[p], key);
     87     }
     88     void Build()
     89     {
     90         int *s = Q ,*e = Q,i;
     91         for (i = 0; i < Mc; ++i)
     92         {
     93             if (chd[0][i])
     94             {
     95                 *e++ = chd[0][i];
     96                 fail[chd[0][i]] = 0;
     97             }
     98         }
     99         while (s != e)
    100         {
    101             int u = *s++;
    102             for (i = 0; i < Mc; ++i)
    103             {
    104                 int &v = chd[u][i];
    105                 if (v)
    106                 {
    107                     *e++ = v;
    108                     fail[v] = chd[fail[u]][i];
    109                 }
    110                 else v = chd[fail[u]][i];
    111             }
    112         }
    113     }
    114     void find(char *T) {
    115         int j=0;
    116         for(int i=0,temp,c;T[i];i++) {
    117             dp[i]=0;
    118             c=idx(T[i]);
    119             while(j&&!chd[j][c]) j=fail[j];
    120             j=chd[j][c];
    121             temp=j;
    122             while(temp) {
    123                 if(val[temp]) {
    124                     //printf("%d
    ",val[temp]);
    125                     if(i-len[temp]<0) //temp已经在目标串中出现,但是不能转移 
    126                         dp[i]=max(dp[i],val[temp]);
    127                     else if(dp[i-len[temp]])
    128                         dp[i]=max(dp[i],dp[i-len[temp]]+val[temp]);
    129                     printf("%d %d %d
    ",i,dp[i],len[temp]);
    130                 }
    131                 temp=fail[temp];
    132             }
    133 
    134         }
    135     }
    136    /* int solve(char *s)
    137     {
    138         int p = 0;
    139         int k,ans = 0;
    140         for (; *s; s++)
    141         {
    142             k = ID[*s - 'a'];
    143             while (!chd[p][k] && p != 0) p = fail[p];
    144 
    145             p = chd[p][k];
    146 
    147             int rt = p;
    148             while (rt != 0 && val[rt] != -1)
    149             {
    150                 ans += val[rt];
    151                 val[rt] = -1;
    152                 rt = fail[rt];
    153             }
    154         }
    155         return ans;
    156     }*/
    157 }ac;
    158 
    159 char s[100100],t[350];
    160 
    161 int main()
    162 {
    163     Read();
    164     int n,val,i;
    165     while (~scanf("%s",s))
    166     {
    167         ac.Reset(); ac.Init();
    168         scanf("%d",&n);
    169         for (i = 0; i < n; ++i){
    170             scanf("%s %d",t,&val);
    171             ac.insert(t,val);
    172         }
    173         ac.Build();
    174         ac.find(s);
    175         //scanf("%s",tr);
    176         printf("%d
    ",ac.dp[strlen(s)-1]);
    177     }
    178     return 0;
    179 }
  • 相关阅读:
    OGG for sqlserver engryption && insert/delete
    MySQL中SQL_CALC_FOUND_ROWS的用法
    VMWARE 虚拟机新增硬盘,格式化分区,并挂载
    Mycat实战之数据迁移(oracle -- mysql)
    MYCAT实战之分片迁移
    mycat实战之性能测试
    Mycat实战之主键数据库自增方式
    对象的创建与克隆
    c#调用c++的dll,错误篇
    java 模拟消息的发送功能
  • 原文地址:https://www.cnblogs.com/nowandforever/p/4728632.html
Copyright © 2020-2023  润新知