Codeforces Gym 100340I Longest Common Subpair 字符串DP
来源:互联网 发布:linux进程查看命令 top 编辑:程序博客网 时间:2024/06/07 08:19
题目大意:
给出两个字符串P和Q, 找出两个字符串A和B使得A, B都是P的无交集子串, 同时也是Q的无交集的字串
问A + B的长度最长情况下, 一个A, B的解
大致思路:
字符串DP, 用dp[i][j]表示以上面P的第i个字符作为结尾和以下面Q的第j个字符作为结尾向前匹配的最大长度
然后f[i][j]表示P的长度为i的前缀和Q的长度为j的前缀的最长公共字串, 于是f[i][j]就相当于dp[i][j]的前缀和
那么将字符串倒着再来一遍, 然后枚举切割点即可, 时间复杂度O(n*n)
因为内存比较紧, 所以数组需要开short以及重复使用
代码如下:
Result : Accepted Memory : 53384 KB Time : 124 ms
/* * Author: Gatevin * Created Time: 2015/9/1 13:25:38 * File Name: C.cpp */#include<iostream>#include<sstream>#include<fstream>#include<vector>#include<list>#include<deque>#include<queue>#include<stack>#include<map>#include<set>#include<bitset>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<cctype>#include<cmath>#include<ctime>#include<iomanip>using namespace std;const double eps(1e-8);typedef long long lint;#define SHOW_MEMORY(x) cout<<sizeof(x)/(1024.*1024.)<<"MB"<<endlchar s[3010];char t[3010];short dp[3010][3010];short f[3010][3010];short f2[3010][3010];int len1, len2;void find(int x, int y, int len){ for(int i = 1; i <= x; i++) for(int j = 1; j <= y; j++) { if(s[i] == t[j]) dp[i][j] = dp[i - 1][j - 1] + 1; if(dp[i][j] == len) { for(int k = i - len + 1; k <= i; k++) printf("%c", s[k]); printf("\n"); return; } }}void find2(int x, int y, int len){ for(int i = len1; i >= x; i--) for(int j = len2; j >= y; j--) { if(s[i] == t[j]) dp[i][j] = dp[i + 1][j + 1] + 1; if(dp[i][j] == len) { for(int k = i; k <= i + len - 1; k++) printf("%c", s[k]); printf("\n"); return; } }}int main(){ freopen("subpair.in", "r", stdin); freopen("subpair.out", "w", stdout); scanf("%s", s + 1); scanf("%s", t + 1); len1 = strlen(s + 1); len2 = strlen(t + 1); for(int i = 1; i <= len1; i++) for(int j = 1; j <= len2; j++) if(s[i] == t[j]) dp[i][j] = dp[i - 1][j - 1] + 1; for(int i = 1; i <= len1; i++) for(int j = 1; j <= len2; j++) { f[i][j] = max(f[i][j - 1], f[i - 1][j]); f[i][j] = max(f[i][j], dp[i][j]); } for(int i = len1; i >= 1; i--) for(int j = len2; j >= 1; j--) if(s[i] == t[j]) dp[i][j] = dp[i + 1][j + 1] + 1; for(int i = len1; i >= 1; i--) for(int j = len2; j >= 1; j--) { f2[i][j] = max(f2[i][j + 1], f2[i + 1][j]); f2[i][j] = max(f2[i][j], dp[i][j]); } int maxL = 0; int ansi = 0, ansj = 0, leni = 0, lenj = 0; for(int i = 0; i <= len1; i++) for(int j = 0; j <= len2; j++) if(maxL < f[i][j] + f2[i + 1][j + 1]) { maxL = f[i][j] + f2[i + 1][j + 1]; ansi = i, ansj = j; leni = f[i][j], lenj = f2[i + 1][j + 1]; } if(f[ansi][ansj] == 0 && f2[ansi + 1][ansj + 1] == 0) { printf("\n\n"); return 0; } if(f[ansi][ansj] && f2[ansi + 1][ansj + 1] == 0) { find(ansi, ansj, leni); printf("\n"); return 0; } if(f[ansi][ansj] == 0 && f2[ansi + 1][ansj + 1]) { printf("\n"); find2(ansi + 1, ansj + 1, lenj); return 0; } find(ansi, ansj, leni); find2(ansi + 1, ansj + 1, lenj); return 0;}
0 0
- Codeforces Gym 100340I Longest Common Subpair 字符串DP
- 【Codeforces Gym 100228 - I】Graph Dp
- CodeForces Gym 100735I
- [DP]Longest Common Subsequence
- Codeforces Gym 100337B Lempel-Ziv Compression 字符串DP
- Codeforces Gym 100325A String Decomposition 字符串DP
- 字符串 Longest Common Prefix
- codeforces Gym 101097 I Sticks
- Codeforces Gym 101164I Cubes
- Codeforces gym 101350A dp
- Codeforces gym 101102 A dp
- UVA_10405 Longest Common Subsequence(DP)
- 14:Longest Common Prefix【字符串】
- Longest Common Subsequence && Substirng【公共子序列及子字符串】【经典dp】
- Codeforces Gym 100338I TV Show DFS
- codeforces Gym 101334 I IP Networks
- codeforces Gym 101341 I Matrix God
- Gym 101341G I love Codeforces 模拟
- Python简单线程同步
- 常用技术
- Python使用条件变量保持线程同步
- sharepoint 2016 学习系列篇(5)-创建一个应用程序网站
- 解决java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC]Error establishing socket异常
- Codeforces Gym 100340I Longest Common Subpair 字符串DP
- ELK日志管理
- 使用队列让线程同步
- 线程之间的通信
- 错误代码:E/FragmentManager(1337): No view found for id 0x7f030005 (com.example.mnews:layout/menu_frame)
- 一个双引号,愁白头
- 同源策略
- 构造函数综合小练习1
- 自定义缓存工具类----sharedPreferences