[HIHO1554] 最短的 Nore0061(DP)
题目链接:http://hihocoder.com/problemset/problem/1554
不能直接暴力,遇到相同的时候贪心给任意一个串。比如下列数据:
aaa
abc
abcaaa
应该在遇到相同的时候DP处理,f(i,j,k)表示ai bj sk的时候字符串的最短长度,还要考虑从s的哪个位置开始找的问题。
比较难发现的一个规律就是,起点不影响状态转移,所以把起点这一维删掉,枚举了一下起点dfs。(这个规律不是我发现的是我猜的
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 const int maxn = 3030; 6 const int maxm = 110; 7 int na, nb, ns; 8 int f[maxm][maxm][maxn]; 9 char a[maxm], b[maxm], s[maxn]; 10 11 int dfs(int i, int j, int k) { 12 if(i == na && j == nb) return 0; 13 if(k == ns) return 0x7f7f7f7f; 14 if(~f[i][j][k]) return f[i][j][k]; 15 int ret = 0x7f7f7f7f; 16 if(i < na && a[i] == s[k]) ret = min(ret, dfs(i+1,j,k+1)+1); 17 if(j < nb && b[j] == s[k]) ret = min(ret, dfs(i,j+1,k+1)+1); 18 ret = min(ret, dfs(i,j,k+1)+1); 19 return f[i][j][k] = ret; 20 } 21 22 signed main() { 23 // freopen("in", "r", stdin); 24 while(~scanf("%s%s%s",a,b,s)) { 25 na = strlen(a); nb = strlen(b); ns = strlen(s); 26 memset(f, -1, sizeof(f)); 27 int ret = 0x7f7f7f7f; 28 for(int i = 0; i < ns; i++) { 29 ret = min(ret, dfs(0,0,i)); 30 } 31 printf("%d\n", ret==0x7f7f7f7f?-1:ret); 32 } 33 return 0; 34 }