largeCommon

来源:互联网 发布:淘宝卖家会员卡设置 编辑:程序博客网 时间:2024/06/10 18:00
Problem Description

给你2个字符串s1,s2。同时给n个不同字符串和每个的价值value。找出一个s1与s2的公共子序列价值最大,价值等于子序列中包含的子串的value的总和(仅计算给出的n)。

Input

对于每组数据,先输入两个字符串s1,s2(1=<|s1|,|s2|<=100),然后一个整数n,然后输入n个字符串和价值value(-1000<=value<=1000)。并且n个串的长度总和小于等于100.所有字符的为小写。

Output

输出最大的价值

Sample Input
ababc
ababc
2
ababc -100
ab 10

Sample Output

20

/* 题解:多模式字符串匹配,(KMP算法是单模式字符串匹配)

构建ac自动机, 
dp[i][j][k]表示 第一个字符串到i,第二个字符串到j,公共序列在自动机上到达k点时的最大value
 dp[i][j][ tree[k][c] ]= max( dp[i-1][j-1][k] + g[ tree[k][c] ] , dp[i][j][ tree[k][c] ]  )
*/

//标程:

#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;#define max(x,y) (x > y ? x : y)const int inf = 1<<30;char s[110], s1[110], s2[110];int dp[110][110][110], p[110], g[110];int tree[110][27];int main(){// freopen("a.txt","r",stdin);    while(scanf("%s",s1+1)!=EOF){scanf("%s",s2+1);int len1 = strlen(s1+1), len2 = strlen(s2+1);int i, j, k, n;memset(tree,0,sizeof(tree));memset(g,0,sizeof(g));memset(p,0,sizeof(p));int total(0);scanf("%d",&n);for(i = 1; i <= n; i ++){int value;scanf("%s%d",s,&value);int len(strlen(s)), u(0);for(j = 0; j < len; j ++){int c(s[j] - 'a');if(! tree[u][c])      tree[u][c] = ++ total;u = tree[u][c];}g[u] = value;}        queue <int> q;          for (i = 0; i < 26; i ++)              if (tree[0][i])                  q.push(tree[0][i]);          while (!q.empty())          {              int r=q.front();              q.pop();              for (int i=0; i<26; i++)              {                  int u=p[r];                  while (u && !tree[u][i] )  u=p[u];                  int val = tree[r][i];                  if(val)                  {                      q.push(val);                      p[val] = tree[u][i];                      g[val] +=  g[p[val]];                  }                  else                      tree[r][i]= tree[u][i];              }          }  for(i = 0; i <= len1; i ++)for(j = 0; j <= len2; j ++)        for(k = 0; k <= total; k ++)dp[i][j][k] = -inf;for(i = 0; i <= len1; i ++)dp[i][0][0] = 0;for(i = 0; i <= len2; i ++)dp[0][i][0] = 0;for(i = 1; i <= len1; i ++)for(j = 1; j <= len2; j ++){for(k = 0; k <= total; k ++){dp[i][j][k] = max(dp[i][j][k], dp[i-1][j][k]);dp[i][j][k] = max(dp[i][j][k], dp[i][j-1][k]);dp[i][j][k] = max(dp[i][j][k], dp[i-1][j-1][k]);}if(s1[i] == s2[j]){int f(s1[i]-'a');for(k = 0; k <= total; k ++)if(dp[i-1][j-1][k] > -inf)dp[i][j][tree[k][f]] = max(dp[i-1][j-1][k]+g[tree[k][f]], dp[i][j][tree[k][f]]);}}int ans(0);for(i = 0; i <= total; i ++)ans = max(ans, dp[len1][len2][i]);printf("%d\n",ans);}return 0;}


0 0
原创粉丝点击