UVa 1625 颜色的长度
2017-02-04 10:01
471 查看
https://vjudge.net/problem/UVA-1625
题意:
输入两个长度分别为n和m的颜色序列,要求按顺序合并成同一个序列,即每次可以把一个序列开头的颜色放到新序列的尾部。对于每个颜色c来说,其跨度L(c)等于最大位置和最小位置之差。
思路:
我们用d(i,j)表示两个序列已经分别移走了i和j个元素时的最小代价。当然为了在状态转移时知道每个字母的状态,我们需要一些预处理。在下面的代码中,sp,ep数组分别用来表示序列1中每个字母的开头位置和结束位置,同样的,sq,eq分别用来表示序列1中每个字母的开头位置和结束位置。每次新增一个字符后,所有已经出现的但没有结束的字符的跨度L(c)都要+1。所以,我们还需要设置一个c数组来记录已经开始但还没有结束的字符数。
这样,转移方程就是dp(i,j)=min(dp(i-1,j)+c[i-1][j],dp(i,j-1)+c[i][j-1])。
接下来再附上一个滚动数组的代码:
题意:
输入两个长度分别为n和m的颜色序列,要求按顺序合并成同一个序列,即每次可以把一个序列开头的颜色放到新序列的尾部。对于每个颜色c来说,其跨度L(c)等于最大位置和最小位置之差。
思路:
我们用d(i,j)表示两个序列已经分别移走了i和j个元素时的最小代价。当然为了在状态转移时知道每个字母的状态,我们需要一些预处理。在下面的代码中,sp,ep数组分别用来表示序列1中每个字母的开头位置和结束位置,同样的,sq,eq分别用来表示序列1中每个字母的开头位置和结束位置。每次新增一个字符后,所有已经出现的但没有结束的字符的跨度L(c)都要+1。所以,我们还需要设置一个c数组来记录已经开始但还没有结束的字符数。
这样,转移方程就是dp(i,j)=min(dp(i-1,j)+c[i-1][j],dp(i,j-1)+c[i][j-1])。
#include<iostream> #include<algorithm> #include<cstring> #include<string> using namespace std; const int maxn = 5000 + 5; const int INF = 10000000; char p[maxn], q[maxn]; int sp[26], sq[26], ep[26], eq[26]; int d[maxn][maxn], c[maxn][maxn]; int main() { //freopen("D:\\txt.txt", "r", stdin); int T, n, m; scanf("%d", &T); while (T--) { scanf("%s%s", p + 1, q + 1); //cout << p + 1 << " " << q + 1 << endl; n = strlen(p + 1); m = strlen(q + 1); //将字母转化成数字 for (int i = 1; i <= n; i++) p[i] -= 'A'; for (int i = 1; i <= m; i++) q[i] -= 'A'; //预处理 for (int i = 0; i < 26; i++) { sp[i] = sq[i] = INF; ep[i] = eq[i] = 0; } //预处理,计算出序列1中每个字符的开始位置和结束位置 for (int i = 1; i <= n; i++) { sp[p[i]] = min(sp[p[i]], i); ep[p[i]] = i; } //预处理序列2 for (int i = 1; i <= m; i++) { sq[q[i]] = min(sq[q[i]], i); eq[q[i]] = i; } for (int i = 0; i <= n; i++) { for (int j = 0; j <= m; j++) { if (!i && !j) continue; int v1 = INF, v2 = INF; if (i) v1 = d[i-1][j] + c[i-1][j]; //从p中取颜色 if (j) v2 = d[i][j - 1] + c[i][j - 1]; //从q中取颜色 d[i][j] = min(v1, v2); //更新c数组 if (i) { c[i][j] = c[i - 1][j]; if (sp[p[i]] == i && sq[p[i]] > j) c[i][j]++; if (ep[p[i]] == i && eq[p[i]] <= j) c[i][j]--; } else if (j) { c[i][j] = c[i][j - 1]; if (sq[q[j]] == j && sp[q[j]] > i) c[i][j]++; if (eq[q[j]] == j && ep[q[j]] <= i) c[i][j]--; } } } cout << d [m] << endl; } return 0; }
接下来再附上一个滚动数组的代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 5000 + 5; const int INF = 1000000000; char p[maxn], q[maxn]; int sp[26], sq[26], ep[26], eq[26]; int d[2][maxn], c[2][maxn]; int main() { int T; scanf("%d", &T); while(T--) { scanf("%s%s", p+1, q+1); int n = strlen(p+1); int m = strlen(q+1); for(int i = 1; i <= n; i++) p[i] -= 'A'; for(int i = 1; i <= m; i++) q[i] -= 'A'; // calculate s and e for(int i = 0; i < 26; i++) { sp[i] = sq[i] = INF; ep[i] = eq[i] = 0; } for(int i = 1; i <= n; i++) { sp[p[i]] = min(sp[p[i]], i); ep[p[i]] = i; } for(int i = 1; i <= m; i++) { sq[q[i]] = min(sq[q[i]], i); eq[q[i]] = i; } // dp int t = 0; memset(c, 0, sizeof(c)); memset(d, 0, sizeof(d)); for(int i = 0; i <= n; i++) { for(int j = 0; j <= m; j++) { if(!i && !j) continue; // calculate d int v1 = INF, v2 = INF; //计算d[i][j], d[i][j]由d[i-1][j]或d[i][j-1]添加一个字母得到 if(i) v1 = d[t^1][j] + c[t^1][j]; // remove from p if(j) v2 = d[t][j - 1] + c[t][j - 1]; // remove from q d[t][j] = min(v1, v2); // calculate c if(i) { c[t][j] = c[t^1][j]; if(sp[p[i]] == i && sq[p[i]] > j) c[t][j]++; //出现新的字母 if(ep[p[i]] == i && eq[p[i]] <= j) c[t][j]--; //一个字母已经结束 } else if(j) { c[t][j] = c[t][j - 1]; if(sq[q[j]] == j && sp[q[j]] > i) c[t][j]++; if(eq[q[j]] == j && ep[q[j]] <= i) c[t][j]--; } } t ^= 1; } printf("%d\n", d[t^1][m]); } return 0; }
相关文章推荐
- 动态规划(颜色的长度,uva 1625)
- UVA1625颜色的长度
- Uva 1625,颜色的长度
- 【UVa1625】颜色的长度
- [UVa1625]颜色的长度
- UVa - 1625 Color Length 颜色的长度 动态规划 重庆一中高2018级竞赛班第十次测试 2016.9.16 Problem 2
- uva1625 颜色的长度
- UVA1625 颜色的长度(color length)(重庆一中高2018级信息学竞赛测验10) 解题报告
- UVA 1625 Color Length 颜色的长度 (预处理+dp)
- 颜色的长度(uva 1625)
- UVa 1625 Color Length (DP)
- uva 1625 - Color Length(dp 里面 L C S 问题解决方式变形)
- 前端常用到的颜色值和长度值设置
- Uva 12012 Detection of Extraterrestrial 求循环节个数为1-n的最长子串长度 KMP
- UVA 455 Periodic Strings (最短周期串长度)
- 例题9-8 颜色的长度 UVa1625
- UITableView Cell 间隔线颜色长度
- Color Length UVA - 1625
- iOS 自定义TextView/TextField光标颜色、长度或高度
- UVa 1625:Color Length(DP)