当前位置:   article > 正文

CF33b-B. String Problem

CF33b-B. String Problem

题目链接

题意:

给定两个字符串,给出n个op。对于每个op可以将一种字母转变为另一个字母,代价为d。需要求出通过上面的变化,让两个字符串相等的最小代价的字符串

题解:
先用Floyd计算出一个字母变换为另一个字母的最小代价,
接下来我们考虑某一个位置,假设初始字符分别是c1,c2,最后变成了 
c0,那么总成本为dp[c1][c0] + dp[c2][c0];也就是c1变成c0的最小成本加上 
c2变成c0的最小成本。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define fi first
  4. #define se second
  5. #define ve vector
  6. #define all(x) (x).begin(), (x).end()
  7. #define rep(i, a, b) for (int i = a; i < b; i++)
  8. #define per(i, a, b) for (int i = a; i >= b; i--)
  9. using pi = pair<int, int>;
  10. inline int red() {
  11. int x;
  12. cin >> x;
  13. return x;
  14. }
  15. void solve() {
  16. string sa, sb;
  17. cin >> sa >> sb;
  18. int n = red();
  19. const int inf = 1e9;
  20. ve dp(26, ve<int>(26, inf));
  21. rep(i, 0, 26) {
  22. dp[i][i] = 0;
  23. }
  24. while (n--) {
  25. char c1, c2;
  26. int d;
  27. cin >> c1 >> c2 >> d;
  28. int x1 = c1 - 'a', x2 = c2 - 'a';
  29. dp[x1][x2] = min(dp[x1][x2], d);
  30. }
  31. if (sa.size() != sb.size()) {
  32. cout << "-1\n";
  33. return ;
  34. }
  35. rep(k, 0, 26) {
  36. rep(i, 0, 26) {
  37. rep(j, 0, 26) {
  38. dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j]);
  39. }
  40. }
  41. }
  42. int len = sa.size(), sum = 0;
  43. string fin_str(len, 'a');
  44. rep(i, 0, len) {
  45. int x = sa[i] - 'a', y = sb[i] - 'a', mn = inf, cur;
  46. rep(j, 0, 26) {
  47. if (dp[x][j] != inf && dp[y][j] != inf && mn > dp[x][j] + dp[y][j]) {
  48. mn = dp[x][j] + dp[y][j];
  49. cur = j;
  50. }
  51. }
  52. if (mn == inf) {
  53. cout << "-1\n";
  54. return ;
  55. }
  56. sum += mn;
  57. fin_str[i] += cur;
  58. }
  59. cout << sum << '\n' << fin_str << '\n';
  60. }
  61. int main() {
  62. ios_base::sync_with_stdio(false);
  63. cin.tie(nullptr);
  64. int t = 1;
  65. while (t--) {
  66. solve();
  67. }
  68. return 0;
  69. }

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号