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
给你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
- largeCommon
- fzu2162 largeCommon
- 2014年春
- C++中空类的大小
- nyoj 94 cigarettes
- Java 类中各成分加载顺序 和 内存中的存放位置
- travel the binary tree by level 2 ( from top to down )
- largeCommon
- 浅谈“三层架构”
- 中位数
- 子页面调用父页面函数
- MySQL安全配置详解
- 《算法导论》笔记 第22章 22.3 深度优先搜索
- 【android 使用两个surfaceview 在摄像机画面上绘图】
- execute、executeQuery和executeUpdate之间的区别
- 工厂模式