CodeForces - 49E Common ancestor(dp)
来源:互联网 发布:js点击左右切换div 编辑:程序博客网 时间:2024/05/22 10:29
题意:有n个替换规则,2个字母可以被替换成一个字母,给出2个串,问这2个串经过一系列的替换后形成的最短且相同的串长度是多少。
做法:我们可以先用区间dp,d[i][j][k]代表i到j区间是否可以变成k这个字母。再利用vector去存一下起点为i,变成k这个字母的终点为哪些,然后就可以进行后来的dp了。设dp[i][j]为第一个串用了i个字母,第二个串用了j个字母经过替换变成相同的串的最短长度。转移就是枚举下一个字母是什么,对于某个dp[i][j],第一个串起点就是i+1,需要利用刚才的vector去找变成枚举的字母的终点。第二个串就是起点是j+1,一样。更新dp[x][y] = min(dp[x][y], dp[i][j]+1)。最后答案就是dp[len1][len2]。
AC代码:
//#pragma comment(linker, "/STACK:102400000,102400000")#include<cstdio>#include<ctype.h>#include<algorithm>#include<iostream>#include<cstring>#include<vector>#include<cstdlib>#include<stack>#include<queue>#include<set>#include<map>#include<cmath>#include<ctime>#include<string.h>#include<string>#include<sstream>#include<bitset>using namespace std;#define ll __int64#define ull unsigned long long#define eps 1e-8#define NMAX 10000000#define MOD 1000000007#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define PI acos(-1)#define mp make_pairtemplate<class T>inline void scan_d(T &ret){ char c; int flag = 0; ret=0; while(((c=getchar())<'0'||c>'9')&&c!='-'); if(c == '-') { flag = 1; c = getchar(); } while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar(); if(flag) ret = -ret;}char s1[55],s2[55],tmp[10];int sub[55][3],n;bool dp1[55][55][30],dp2[55][55][30];vector<int>v1[55][30],v2[55][30];vector<int>::iterator it1,it2;void getdp(char *s, int len, bool dp[][55][30], vector<int> v[][30]){ for(int i = 1; i <= len; i++) dp[i][i][s[i]-'a'] = 1; for(int L = 2; L <= len; L++) for(int i = 1; i + L - 1 <= len; i++) for(int k = i; k < i+L-1; k++) for(int j = 1; j <= n; j++) dp[i][i+L-1][sub[j][2]] |= dp[i][k][sub[j][0]]&&dp[k+1][i+L-1][sub[j][1]]; for(int i = 1; i <= len; i++) for(int j = i; j <= len; j++) for(int k = 0; k < 26; k++) if(dp[i][j][k]) v[i][k].push_back(j);}int dp[55][55];int main(){#ifdef GLQ freopen("input.txt","r",stdin);// freopen("o.txt","w",stdout);#endif scanf("%s%s",s1+1,s2+1); scanf("%d",&n); for(int i = 1; i <= n; i++) { scanf("%s",tmp); sub[i][0] = tmp[3]-'a'; sub[i][1] = tmp[4]-'a'; sub[i][2] = tmp[0]-'a'; } int len1 = strlen(s1+1), len2 = strlen(s2+1); memset(dp1,0,sizeof(dp1)); memset(dp2,0,sizeof(dp2)); for(int i = 1; i <= 55; i++) for(int j = 0; j < 30; j++) { v1[i][j].clear(); v2[i][j].clear(); } getdp(s1,len1,dp1,v1); getdp(s2,len2,dp2,v2); for(int i = 0; i <= len1; i++) for(int j = 0; j <= len2; j++) dp[i][j] = 100; dp[0][0] = 0; for(int i = 0; i < len1; i++) for(int j = 0; j < len2; j++) if(dp[i][j] != 100) for(int k = 0; k < 26; k++) for(it1 = v1[i+1][k].begin(); it1 != v1[i+1][k].end(); it1++) for(it2 = v2[j+1][k].begin(); it2 != v2[j+1][k].end(); it2++) dp[*it1][*it2] = min(dp[*it1][*it2],dp[i][j]+1); if(dp[len1][len2] == 100) printf("-1\n"); else printf("%d\n",dp[len1][len2]); return 0;}
0 0
- CodeForces - 49E Common ancestor(dp)
- Codeforces Beta Round #46 (Div. 2) E. Common ancestor
- LCA(Least Common Ancestor)
- 235-e-Lowest Common Ancestor of a Binary Search Tree
- ICPCCamp 2017-Day1 E.Lowest Common Ancestor(树链剖分/lct)
- CodeForces 148E Porcelain(dp+背包)
- Codeforces 598E:Chocolate Bar(DP)
- Codeforces 166E Tetrahedron(dp)
- Codeforces 148E Porcelain (dp)
- Codeforces 743E(二分+状压dp)
- Codeforces-797E-Array Queries(dp)
- CodeForces 731 E.Funny Game(dp)
- codeforces 166-E. Tetrahedron(预处理+dp)
- CodeForces 14 E.Camels(dp)
- 【CodeForces 158E】Phone Talks(DP)
- Codeforces 864E Fire (DP)
- 【dp】codeforces 83E
- codeforces-731E-dp
- MongoDB的一些简单CRUD操作
- CF 275 div2 D. Interesting Array (线段树)
- Binary_Indexed_Tree(树状数组)
- 求1000!的结果中包含多少个0?注:1000! = 1×2×3×4×5×...×999×1000(求阶乘)
- 党援之众,无竞大义。群迷之中,无辩正论。
- CodeForces - 49E Common ancestor(dp)
- ubuntu12.04的NFS配置
- MVC和MVVM的区别和联系
- failed: ERROE OCINlsEnvironmentVariableGet(OCI_NLS_CHARSET_ID) Check NLS settings etc. at
- 深入浅出讲解:php的socket通信
- 用Ajax+js+jQuery实现无闪烁定时刷新页面
- eclipse快捷键
- 线索二叉树
- poj 1517 u Calculate e