#include <algorithm> #include <cstdio> #include <utility> #include "message.h" const int N = 100002; const int MAX_MESSAGES = 1000; char orig[N], dest[N]; int x1, x2; std::pair<int, int> row[N][2], column[2][N]; inline std::pair<int, int> &dp(int x, int y){ return (x < x1) ? column[0][y]:row[x][y & 1]; } int main(){ int nNodes = NumberOfNodes(); int myNodeId = MyNodeId(); int n, m; scanf("%d%d", &n, &m); scanf("%s", orig + 1); scanf("%s", dest + 1); const int nMessages = std::min(MAX_MESSAGES, m); x1 = 1 + (n * myNodeId) / nNodes; x2 = 1 + (n * (myNodeId + 1)) / nNodes; column[0][0] = {x1 - 1, 0}; if(myNodeId == 0) for(int y = 0; y <= m; y++) column[0][y] = {y, 0}; for(int x = x1; x < x2; ++x) row[x][0] = {x, 0}; for(int i = 0; i < nMessages; i++){ int y1 = 1 + (m * i) / nMessages; int y2 = 1 + (m * (i + 1)) / nMessages; if(myNodeId){ Receive(myNodeId - 1); for(int y = y1; y < y2; ++y){ column[0][y].first = GetInt(myNodeId - 1); column[0][y].second = GetInt(myNodeId - 1); } } for(int y = y1; y < y2; ++y){ for(int x = x1; x < x2; x++){ dp(x, y) = dp(x - 1, y - 1); if(orig[x] != dest[y]){ dp(x, y).first++; dp(x, y).second += (orig[x] < dest[y]); // nie na odwrót? dp(x - 1, y).first++; dp(x, y) = std::min(dp(x, y), dp(x - 1, y)); dp(x - 1, y).first--; dp(x, y - 1).first++; dp(x, y) = std::min(dp(x, y), dp(x, y - 1)); dp(x, y - 1).first--; } } column[1][y] = dp(x2 - 1, y); } if(myNodeId != nNodes - 1) { for(int y = y1; y < y2; ++y){ PutInt(myNodeId + 1, column[1][y].first); PutInt(myNodeId + 1, column[1][y].second); } Send(myNodeId + 1); } } if(myNodeId == nNodes - 1) printf("%d %d\n", dp(n, m).first, dp(n, m).second); return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | #include <algorithm> #include <cstdio> #include <utility> #include "message.h" const int N = 100002; const int MAX_MESSAGES = 1000; char orig[N], dest[N]; int x1, x2; std::pair<int, int> row[N][2], column[2][N]; inline std::pair<int, int> &dp(int x, int y){ return (x < x1) ? column[0][y]:row[x][y & 1]; } int main(){ int nNodes = NumberOfNodes(); int myNodeId = MyNodeId(); int n, m; scanf("%d%d", &n, &m); scanf("%s", orig + 1); scanf("%s", dest + 1); const int nMessages = std::min(MAX_MESSAGES, m); x1 = 1 + (n * myNodeId) / nNodes; x2 = 1 + (n * (myNodeId + 1)) / nNodes; column[0][0] = {x1 - 1, 0}; if(myNodeId == 0) for(int y = 0; y <= m; y++) column[0][y] = {y, 0}; for(int x = x1; x < x2; ++x) row[x][0] = {x, 0}; for(int i = 0; i < nMessages; i++){ int y1 = 1 + (m * i) / nMessages; int y2 = 1 + (m * (i + 1)) / nMessages; if(myNodeId){ Receive(myNodeId - 1); for(int y = y1; y < y2; ++y){ column[0][y].first = GetInt(myNodeId - 1); column[0][y].second = GetInt(myNodeId - 1); } } for(int y = y1; y < y2; ++y){ for(int x = x1; x < x2; x++){ dp(x, y) = dp(x - 1, y - 1); if(orig[x] != dest[y]){ dp(x, y).first++; dp(x, y).second += (orig[x] < dest[y]); // nie na odwrót? dp(x - 1, y).first++; dp(x, y) = std::min(dp(x, y), dp(x - 1, y)); dp(x - 1, y).first--; dp(x, y - 1).first++; dp(x, y) = std::min(dp(x, y), dp(x, y - 1)); dp(x, y - 1).first--; } } column[1][y] = dp(x2 - 1, y); } if(myNodeId != nNodes - 1) { for(int y = y1; y < y2; ++y){ PutInt(myNodeId + 1, column[1][y].first); PutInt(myNodeId + 1, column[1][y].second); } Send(myNodeId + 1); } } if(myNodeId == nNodes - 1) printf("%d %d\n", dp(n, m).first, dp(n, m).second); return 0; } |