Color Length UVA

题目:题目链接

题意:输入两个长度分别为n和m的颜色序列,要求按顺序合并成同一个序列,即每次可以把一个序列开头的颜色放到新序列的尾部。对于每个颜色c来说,其跨度L(c)等于最大位置和最小位置之差,输出各颜色跨度之和。

思路:设d(i, j)表示两个序列分别移走了i和j个元素,还需要多少费用。每移一次,我们需要对已经出现但没有结束的颜色跨度加一,用数组c表示已经开始但没有结束的颜色数量,我们得到状态转移方程:dp(i,j)=min(dp(i-1,j)+c[i-1][j],dp(i,j-1)+c[i][j-1])

AC代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <string>
 9 #include <map>
10 #include <set>
11 #include <unordered_map>
12 #include <unordered_set>
13 #include <queue>
14 #include <stack>
15 #include <list>
16 
17 #define FRER() freopen("in.txt", "r", stdin)
18 #define FREW() freopen("out.txt", "w", stdout)
19 
20 #define INF 0x3f3f3f3f
21 
22 using namespace std;
23 
24 const int maxn = 5000 + 5;
25 
26 char str[maxn], ptr[maxn];
27 
28 int ss[26], sp[26], es[26], ep[26];
29 
30 int d[maxn][maxn], c[maxn][maxn];
31 
32 int main()
33 {
34     ios::sync_with_stdio(0);
35     cin.tie(0);
36     int T;
37     cin >> T;
38     while(T--) {
39         cin >> (str + 1) >> (ptr + 1);
40 
41         int n = strlen(str + 1), m = strlen(ptr + 1);
42 
43         memset(ss, INF, sizeof(ss));
44         memset(sp, INF, sizeof(sp));
45         memset(es, 0, sizeof(es));
46         memset(ep, 0, sizeof(ep));
47 
48         for(int i = 1; i <= n; ++i) {
49             ss[str[i] - 'A'] = min(ss[str[i] - 'A'], i);
50             es[str[i] - 'A'] = i;
51         }
52         for(int i = 1; i <= m; ++i) {
53             sp[ptr[i] - 'A'] = min(sp[ptr[i] - 'A'], i);
54             ep[ptr[i] - 'A'] = i;
55         }
56 
57         for(int i = 0; i <= n; ++i) {
58             for(int j = 0; j <= m; ++j) {
59                 if(!i && !j) continue;
60                 int v1 = INF, v2 = INF;
61                 if(i) v1 = d[i - 1][j] + c[i - 1][j];
62                 if(j) v2 = d[i][j - 1] + c[i][j - 1];
63                 d[i][j] = min(v1, v2);
64 
65                 if(i) {
66                     c[i][j] = c[i - 1][j];
67                     if(ss[str[i] - 'A'] == i && sp[str[i] - 'A'] > j) c[i][j]++;
68                     if(es[str[i] - 'A'] == i && ep[str[i] - 'A'] <= j) c[i][j]--;
69                 }
70 
71                 else if(j) {
72                     c[i][j] = c[i][j - 1];
73                     if(sp[ptr[j] - 'A'] == j && ss[ptr[j] - 'A'] > i) c[i][j]++;
74                     if(ep[ptr[j] - 'A'] == j && es[ptr[j] - 'A'] <= i) c[i][j]--;
75                 }
76             }
77         }
78 
79         cout << d[n][m] << endl;
80     }
81     return 0;
82 }
原文地址:https://www.cnblogs.com/fan-jiaming/p/10321163.html