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\n", 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\n",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\n",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\n",ac.dp[strlen(s)-1]);
177     }
178     return 0;
179 }

 

posted @ 2015-08-13 22:31  NowAndForever  阅读(174)  评论(0编辑  收藏  举报