fzu2162 largeCommon
来源:互联网 发布:js点击显示div 编辑:程序博客网 时间:2024/06/13 12:17
Problem 2162 largeCommon
Accept: 3 Submit: 46
Time Limit: 1000 mSec Memory Limit : 32768 KB
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
ababcababc
2
ababc -100
ab 10
Sample Output
20
Submit Back Status
构建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<cstdio>#include<cstring>#include<iostream>#include<queue>using namespace std;#define inf (1<<30)char s1[111],s2[111],s[111];int tree[111][27];int f[111][111];int n,m,tot,ans,len1,len2;int g[111], p[111];int dp[111][111][111];int idx( char c){ return c-'a';}int main(){ while (scanf("%s",s1+1)!=EOF) { scanf("%s",s2+1); len1=strlen(s1+1), len2=strlen(s2+1); memset(tree,0,sizeof(tree)); memset( g, 0 ,sizeof(g) ); memset( p, 0 ,sizeof(p) ); scanf("%d",&n); tot=0; for (int i=1; i<=n; i++) { int x; scanf("%s%d",s,&x); int len=strlen(s),u=0; for (int j=0; j<len; j++) { int c=idx(s[j]); if ( !tree[u][c] ) tree[u][c]=++tot; u=tree[u][c]; } g[u]=x; } queue <int> q; for (int 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 v= tree[r][i]; if ( v ) { q.push( v ); p[ v ] = tree[u][i]; g[ v ] += g[ p[v] ]; } else tree[r][i]= tree[u][i]; } } for (int i=0; i<=len1; i++) for (int j=0; j<=len2; j++) for (int k=0; k<=tot ; k++) dp[i][j][k]=-inf; for (int i=0; i<=len1; i++) dp[i][0][0]=0; for (int i=0; i<=len2; i++) dp[0][i][0]=0; for (int i=1; i<=len1; i++) for (int j=1; j<=len2; j++) { for (int k=0; k<=tot; 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 c= idx(s1[i]); for (int k=0; k<=tot; k++) if(dp[i-1][j-1][k]>-inf ) dp[i][j][ tree[k][c] ]= max( dp[i-1][j-1][k] + g[ tree[k][c] ] , dp[i][j][ tree[k][c] ] ); } } ans= 0; for (int i=0; i<=tot ;i++) ans= max( ans , dp[len1][len2][i]); printf("%d\n",ans); } return 0;}
0 0
- fzu2162 largeCommon
- largeCommon
- 在win7中如何配置IIS
- tiny6410 Miscdevice driver<1>
- Session的生命周期问题
- 多态性与虚函数2
- PHP CURL 发送请求
- fzu2162 largeCommon
- 解决窗口嵌套问题
- c语言与java语言判断一个点在一个多边形里面
- FI---FI tables的结构和关系总览图
- Android 消息推送 -- Xinge Push[客户端数据接收处理]
- Pat(Advanced Level)Practice--1056(Mice and Rice)
- 内网ip映射到外网软件之NAT123端口映射使用方法
- Mysql设置允许远程连接
- FI--关于凭证的修改和冲销操作