Advertisement
a53

lenes

a53
Sep 30th, 2017
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.30 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #define NMax 1010
  5. #define VMax 1010
  6. #define oo 0x3f3f3f3f
  7. using namespace std;
  8. const char IN[] = "lenes.in", OUT[] = "lenes.out";
  9. int Case, N, M, k1, k2;
  10. int Mat[NMax][NMax];
  11. int Sum[NMax], V[NMax], left[NMax], right[NMax];
  12.  
  13. int get_line_sum( int lin, int k, bool up = true, bool down = true )
  14. {
  15.  
  16. int res = Sum[lin];
  17.  
  18. static int v[VMax];
  19. memset(v, 0, sizeof(v));
  20.  
  21. for ( int i = 1; i <= M; ++ i ) {
  22. if ( up )
  23. ++ v[ Mat[lin - 1][i] ];
  24. if ( down )
  25. ++ v[ Mat[lin + 1][i] ];
  26. }
  27.  
  28. for ( int i = 0; i < VMax && k ; ++ i )
  29. if ( k >= v[i] ) {
  30. res += i * v[i];
  31. k -= v[i];
  32. } else if ( v[i] ) {
  33. res += k * i;
  34. k = 0;
  35. }
  36.  
  37. return res;
  38. }
  39.  
  40. int case1()
  41. {
  42.  
  43. int ret = get_line_sum(1, k1);
  44.  
  45. for ( int i = 1; i <= N; ++ i )
  46. ret = min( ret, get_line_sum(i, k1));
  47.  
  48. return ret;
  49. }
  50.  
  51. int case2()
  52. {
  53.  
  54. int ret = oo;
  55.  
  56. for ( int i = 1; i <= N; ++ i )
  57. V[i] = get_line_sum(i, k2);
  58.  
  59. left[1] = V[1];
  60. for ( int i = 2; i <= N; ++ i )
  61. left[i] = min(V[i], left[i - 1]);
  62.  
  63. right[N] = V[N];
  64. for ( int i = N - 1; i > 0; -- i )
  65. right[i] = min(V[i], right[i + 1]);
  66.  
  67.  
  68. // computing distant lines
  69. for ( int i = 1; i <= N; ++ i ) {
  70. int r = get_line_sum(i, k1);
  71. int other = oo;
  72.  
  73. if ( i > 3 ) other = min(other, left[i - 3]);
  74. if ( i < N - 2) other = min(other, right[i + 3]);
  75.  
  76. ret = min(ret, r + other);
  77. }
  78.  
  79. // computing adiacent lines
  80. for ( int i = 1; i < N; ++ i ) {
  81.  
  82. int r1 = get_line_sum(i, k1 , true, false);
  83. int r2 = get_line_sum(i + 1, k2, false, true);
  84.  
  85. ret = min( ret, r1 + r2 );
  86.  
  87. r1 = get_line_sum(i, k2 , true, false);
  88. r2 = get_line_sum(i + 1, k1, false, true);
  89.  
  90. ret = min( ret, r1 + r2 );
  91. }
  92.  
  93. //fprintf(stderr, "%d\n", ret);
  94. // computing common margin lines
  95.  
  96. bool parity = true;
  97.  
  98. for ( int i = 1; i < N - 1; ++ i ) {
  99.  
  100. int sum = Sum[i] + Sum[i + 2];
  101. int up = i - 1;
  102. int mid = i + 1;
  103. int down = i + 3;
  104. int index_up = 1;
  105. int index_down = 1;
  106.  
  107. for ( int j = 1; j <= M && j <= k1 + k2; ++ j )
  108. sum += Mat[mid][j];
  109.  
  110. // adding extra elements
  111. for ( int j = M + 1; j <= k1 + k2; ++ j ) {
  112. if ( index_up <= k1 && Mat[up][index_up] <= Mat[down][index_down] || index_down > k2 ) {
  113. sum += Mat[up][index_up];
  114. ++ index_up;
  115. } else {
  116. sum += Mat[down][index_down];
  117. ++ index_down;
  118. }
  119. }
  120.  
  121. ret = min(ret, sum);
  122. //fprintf(stderr, "begining with: (%d, %d, %d)\n", index_up - 1, min(M, k1 + k2), index_down - 1);
  123. for ( int j = min(M, k1 + k2); j > 0; -- j ) {
  124. sum -= Mat[mid][j];
  125. if ( index_up <= k1 && Mat[up][index_up] <= Mat[down][index_down] || index_down > k2 ) {
  126. sum += Mat[up][index_up];
  127. ++ index_up;
  128. } else {
  129. sum += Mat[down][index_down];
  130. ++ index_down;
  131. }
  132.  
  133. ret = min( ret, sum );
  134. if ( ret == sum ) {
  135. //fprintf(stderr, "(up: %d, mid: %d, down: %d -> %d\n", index_up - 1, j - 1, index_down - 1, ret);
  136. }
  137. }
  138.  
  139. if ( parity ) {
  140. parity = false;
  141. -- i;
  142. } else {
  143. parity = true;
  144. }
  145.  
  146. swap( k1, k2 );
  147.  
  148. }
  149.  
  150. return ret;
  151. }
  152.  
  153. int (*Work[])() = { case1, case2 };
  154.  
  155. int main()
  156. {
  157.  
  158. freopen(IN, "r", stdin);
  159. freopen(OUT, "w", stdout);
  160.  
  161. scanf("%d%d%d%d%d", &Case, &N, &M, &k1, &k2);
  162.  
  163. for ( int i = 1; i <= N; ++ i)
  164. for ( int j = 1; j <= M; ++ j )
  165. scanf("%d", &Mat[j][i]);
  166.  
  167. swap(N, M);
  168.  
  169. for ( int i = 1; i <= N; ++ i )
  170. for ( int j = 1; j <= M; ++ j )
  171. Sum[i] += Mat[i][j];
  172.  
  173. for ( int i = 1; i <= M; ++ i )
  174. Mat[0][i] = Mat[N + 1][i] = VMax - 1;
  175.  
  176. for ( int i = 1; i <= N; ++ i )
  177. sort( Mat[i] + 1, Mat[i] + M + 1);
  178.  
  179. printf("%d\n", Work[Case - 1]());
  180.  
  181. return 0;
  182. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement