[HIHO1554] 最短的 Nore0061(DP)

Posted tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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 }

 

以上是关于[HIHO1554] 最短的 Nore0061(DP)的主要内容,如果未能解决你的问题,请参考以下文章

如何使用正则表达式找到最短的重叠匹配?

最短的计算大数乘法的c程序

C语言:输入n和n个字符串,输出其中最短的字符串。若长度相同则输出出现较早的那一个

!!!!!!!1怎样在最短的时间内掌握asp?

在单词中找到最短的重复周期?

最短的定时时间和最长定时时间