|
| 1 | +```cpp |
| 2 | +#include <bits/stdc++.h> |
| 3 | +using namespace std; |
| 4 | +using ll = long long; |
| 5 | + |
| 6 | +ll A[2001][201]{}, S[2001][201]{}; |
| 7 | +ll le[2001]{}, ri[2001]{}; |
| 8 | +ll dist[2001][2001]{}, up[2001][2001]{}, down[2001][2001]{}, mid[2001][2001]{}; |
| 9 | +pair<int, int> p[200002]{}; |
| 10 | + |
| 11 | +int main(){ |
| 12 | + cin.tie(0)->sync_with_stdio(0); |
| 13 | + |
| 14 | + int R, C; |
| 15 | + cin>>R>>C; |
| 16 | + |
| 17 | + for(int i=1;i<=R;i++) { |
| 18 | + for(int j=1;j<=C;j++) { |
| 19 | + cin>>A[i][j]; |
| 20 | + S[i][j] = S[i][j-1] + A[i][j]; |
| 21 | + } |
| 22 | + le[i] = le[i-1] + A[i][1]; |
| 23 | + ri[i] = ri[i-1] + A[i][C]; |
| 24 | + } |
| 25 | + |
| 26 | + for(int j=1;j<=R;j++) { |
| 27 | + up[1][j] = S[1][C] + ri[j]-ri[1]; |
| 28 | + up[j][1] = S[1][C] + le[j]-le[1]; |
| 29 | + } |
| 30 | + for(int i=2;i<=R;i++) for(int j=2;j<=R;j++) { |
| 31 | + up[i][j] = min(up[i-1][j] + A[i][1], up[i][j-1] + A[j][C]); |
| 32 | + if(i<j) { |
| 33 | + up[i][j] = min(up[i][j], S[i][C] + ri[j]-ri[i]); |
| 34 | + } |
| 35 | + else{ |
| 36 | + up[i][j] = min(up[i][j], S[j][C] + le[i]-le[j]); |
| 37 | + } |
| 38 | + } |
| 39 | + |
| 40 | + for(int j=1;j<=R;j++) { |
| 41 | + down[R][j] = S[R][C] + ri[R-1]-ri[j-1]; |
| 42 | + down[j][R] = S[R][C] + le[R-1]-le[j-1]; |
| 43 | + } |
| 44 | + for(int i=R-1;i>=1;i--) for(int j=R-1;j>=1;j--) { |
| 45 | + down[i][j] = min(down[i+1][j] + A[i][1], down[i][j+1] + A[j][C]); |
| 46 | + if(i<j) { |
| 47 | + down[i][j] = min(down[i][j], S[j][C] + le[j-1]-le[i-1]); |
| 48 | + } |
| 49 | + else{ |
| 50 | + down[i][j] = min(down[i][j], S[i][C] + ri[i-1]-ri[j-1]); |
| 51 | + } |
| 52 | + } |
| 53 | + |
| 54 | + for(int i=1;i<=R;i++) mid[i][i] = S[i][C]; |
| 55 | + for(int k=1;k<R;k++) for(int i=1;i+k<=R;i++) { |
| 56 | + int j = i+k; |
| 57 | + mid[i][j] = min({mid[i+1][j] + A[i][1], mid[i][j-1] + A[j][C], S[i][C] + ri[j]-ri[i], S[j][C] + le[j-1]-le[i-1]}); |
| 58 | + mid[j][i] = min({mid[j-1][i] + A[j][1], mid[j][i+1] + A[i][C], S[i][C] + le[j]-le[i], S[j][C] + ri[j-1]-ri[i-1]}); |
| 59 | + } |
| 60 | + |
| 61 | + for(int i=1;i<=R;i++) for(int j=1;j<=R;j++) { |
| 62 | + dist[i][j] = min({up[i][j], down[i][j], mid[i][j]}); |
| 63 | + } |
| 64 | + |
| 65 | + p[0] = {1,1}; |
| 66 | + int D; |
| 67 | + cin>>D; |
| 68 | + for(int i=1;i<=D;i++) cin>>p[i].first>>p[i].second; |
| 69 | + |
| 70 | + ll ans = A[1][1]; |
| 71 | + for(int i=1;i<=D;i++) { |
| 72 | + auto [pr,pc] = p[i-1]; |
| 73 | + auto [r,c] = p[i]; |
| 74 | + |
| 75 | + if(pr == r) { |
| 76 | + if(pc < c) { |
| 77 | + ll res1 = S[r][c] - S[r][pc]; |
| 78 | + ll res2 = dist[r][r] + max(0LL, S[r][C-1]-S[r][c-1]); |
| 79 | + if(pc == 1) res2 -= A[pr][1]; |
| 80 | + else res2 += S[pr][pc-1]-S[pr][1]; |
| 81 | + ans += min(res1, res2); |
| 82 | + } |
| 83 | + else{ |
| 84 | + ll res1 = S[r][pc-1] - S[r][c-1]; |
| 85 | + ll res2 = dist[r][r] + max(0LL, S[r][c]-S[r][1]); |
| 86 | + if(pc == C) res2 -= A[pr][C]; |
| 87 | + else res2 += S[pr][C-1]-S[pr][pc]; |
| 88 | + ans += min(res1, res2); |
| 89 | + } |
| 90 | + } |
| 91 | + else { |
| 92 | + // prev에서 왼쪽으로, cur에서 오른쪽으로 |
| 93 | + ll res1 = dist[pr][r] + max(0LL, S[r][C-1]-S[r][c-1]); |
| 94 | + if(pc == 1) res1 -= A[pr][1]; |
| 95 | + else res1 += S[pr][pc-1]-S[pr][1]; |
| 96 | + // prev에서 오른쪽으로, cur에서 왼쪽으로 |
| 97 | + ll res2 = dist[r][pr] + max(0LL, S[r][c]-S[r][1]); |
| 98 | + if(pc == C) res2 -= A[pr][C]; |
| 99 | + else res2 += S[pr][C-1]-S[pr][pc]; |
| 100 | + // prev에서 왼쪽으로, cur에서 왼쪽으로 |
| 101 | + ll res3 = (pr<r ? le[r-1]-le[pr] : le[pr-1]-le[r]) + S[pr][pc-1] + S[r][c]; |
| 102 | + // prev에서 오른쪽으로, cur에서 오른쪽으로 |
| 103 | + ll res4 = (pr<r ? ri[r-1]-ri[pr] : ri[pr-1]-ri[r]) + S[pr][C]-S[pr][pc] + S[r][C]-S[r][c-1]; |
| 104 | + |
| 105 | + ll res = min({res1, res2, res3, res4}); |
| 106 | + |
| 107 | + ans += res; |
| 108 | + } |
| 109 | + |
| 110 | + } |
| 111 | + cout<<ans; |
| 112 | + |
| 113 | +} |
| 114 | +``` |
0 commit comments