#include <cstdio> #include <vector> #include <cmath> using namespace std; char in_expr[100001]; char cleaned_expr[100001]; bool deletions[51]; // bestdeletes[i][j] - best deletion of j N's from i-th segment vector<vector<int>> bestdeletes; int cleaned_n; long long compute_naviasity(); int main() { int n, k; scanf("%d %d", &n, &k); k-=1; scanf("%s", in_expr); // EXPRESSION CLEANUP // B - break, N - () int balance = 0; int cleaned_i = 0; int total_n = 0; char last_thing = 'X'; for (int i = 0; i < n; ++i) { if (in_expr[i] == '(') { balance += 1; // printf("Inserting (\n"); cleaned_expr[cleaned_i] = '('; last_thing = '('; } else { balance -= 1; if (last_thing == '(') { // replace '(' with 'N' cleaned_i--; // printf("Replacing ( with N\n"); cleaned_expr[cleaned_i] = 'N'; last_thing = 'N'; total_n++; } else if (balance < 0) { if (last_thing == 'B') { // just merge it into the barrier cleaned_i--; } else { // create a barrier // printf("Inserting B\n"); cleaned_expr[cleaned_i] = 'B'; last_thing = 'B'; } balance = 0; } else { // a )) sequence // printf("Inserting )\n"); cleaned_expr[cleaned_i] = ')'; last_thing = ')'; } } cleaned_i++; } cleaned_n = cleaned_i; // now go right to left and remove excess '(' // excess ')' are already removed cleaned_i--; balance = 0; for (; cleaned_i >= 0; --cleaned_i) { if (cleaned_expr[cleaned_i] == ')') { balance += 1; } else if (cleaned_expr[cleaned_i] == '(') { balance -= 1; if (balance < 0) { cleaned_expr[cleaned_i] = 'B'; balance = 0; } } } if (total_n <= k) { printf("0\n"); return 0; } // int aridx = 0; // int segment_start = 0; // int segment_end = 0; // // while(true) { // if (segment_start >= cleaned_n) { // break; // } // vector<int> newsegment; // // int n_in_segment = 0; // // while (cleaned_expr[segment_end] != 'B') { // if (cleaned_expr[segment_end] == 'N') { // n_in_segment += 1; // } // segment_end++; // } // if (n_in_segment == 0) { // // BB or array end // segment_end++; // segment_start = segment_end; // continue; // } // // // calculate k-removals // for (int krems = 1; krems < n_in_segment && krems <= k; ++krems) { // // remval is the best reduction of naviasity when using krems breaks // int remval = 0; // // // TODO: jak to zrobić lepiej niż wykładniczo // // newsegment.push_back(remval); // } // newsegment.push_back() // // bestdeletes.push_back(newsegment); // } // for (int i = 0; i < cleaned_n; ++i) { // printf("%c", cleaned_expr[i]); // } // printf("\n"); long long expnum = 1; for (int i = 0; i < total_n; ++i) { expnum *= 2; } long long max_naviasity = compute_naviasity(); long long min_naviasity = max_naviasity; for (long long i = 1; i < expnum; ++i) { for (int j = 0; j < 50; ++j) { deletions[j] = false; } long long xcopy = i; int d_idx = 0; int yess = 0; while(xcopy > 0) { deletions[d_idx] = xcopy%2; if (deletions[d_idx]) { yess++; } d_idx++; xcopy /= 2; } if (yess != k) { continue; } long long nav = compute_naviasity(); // DEBUG START // printf("result for: "); // xcopy = i; // while(xcopy > 0) { // printf("%d", xcopy%2); // xcopy /= 2; // } // printf(" : %d\n", nav); // DEBUG END if (nav < min_naviasity) { min_naviasity = nav; } } printf("%lld\n", min_naviasity); return 0; } long long compute_naviasity() { int total_naviasity = 0; int prev_on_level[30]; for(int i = 0; i < 30; ++i){ prev_on_level[i] = 0; } int seen_n = 0; int current_level = 0; for (int i = 0; i < cleaned_n; ++i) { if (cleaned_expr[i] == '(') { current_level++; } else if (cleaned_expr[i] == 'B') { for(int i = 0; i < 30; ++i){ prev_on_level[i] = 0; } current_level = 0; } else if (cleaned_expr[i] == 'N') { if (deletions[seen_n]) { // treat as 'B' for(int i = 0; i < 30; ++i){ prev_on_level[i] = 0; } current_level = 0; } else { total_naviasity += prev_on_level[current_level]+1; prev_on_level[current_level] ++; } seen_n += 1; } else if (cleaned_expr[i] == ')') { // reset current streak prev_on_level[current_level] = 0; current_level--; if (current_level < 0) { current_level = 0; } else { total_naviasity += prev_on_level[current_level]+1; prev_on_level[current_level] ++; } } } return total_naviasity; }
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 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | #include <cstdio> #include <vector> #include <cmath> using namespace std; char in_expr[100001]; char cleaned_expr[100001]; bool deletions[51]; // bestdeletes[i][j] - best deletion of j N's from i-th segment vector<vector<int>> bestdeletes; int cleaned_n; long long compute_naviasity(); int main() { int n, k; scanf("%d %d", &n, &k); k-=1; scanf("%s", in_expr); // EXPRESSION CLEANUP // B - break, N - () int balance = 0; int cleaned_i = 0; int total_n = 0; char last_thing = 'X'; for (int i = 0; i < n; ++i) { if (in_expr[i] == '(') { balance += 1; // printf("Inserting (\n"); cleaned_expr[cleaned_i] = '('; last_thing = '('; } else { balance -= 1; if (last_thing == '(') { // replace '(' with 'N' cleaned_i--; // printf("Replacing ( with N\n"); cleaned_expr[cleaned_i] = 'N'; last_thing = 'N'; total_n++; } else if (balance < 0) { if (last_thing == 'B') { // just merge it into the barrier cleaned_i--; } else { // create a barrier // printf("Inserting B\n"); cleaned_expr[cleaned_i] = 'B'; last_thing = 'B'; } balance = 0; } else { // a )) sequence // printf("Inserting )\n"); cleaned_expr[cleaned_i] = ')'; last_thing = ')'; } } cleaned_i++; } cleaned_n = cleaned_i; // now go right to left and remove excess '(' // excess ')' are already removed cleaned_i--; balance = 0; for (; cleaned_i >= 0; --cleaned_i) { if (cleaned_expr[cleaned_i] == ')') { balance += 1; } else if (cleaned_expr[cleaned_i] == '(') { balance -= 1; if (balance < 0) { cleaned_expr[cleaned_i] = 'B'; balance = 0; } } } if (total_n <= k) { printf("0\n"); return 0; } // int aridx = 0; // int segment_start = 0; // int segment_end = 0; // // while(true) { // if (segment_start >= cleaned_n) { // break; // } // vector<int> newsegment; // // int n_in_segment = 0; // // while (cleaned_expr[segment_end] != 'B') { // if (cleaned_expr[segment_end] == 'N') { // n_in_segment += 1; // } // segment_end++; // } // if (n_in_segment == 0) { // // BB or array end // segment_end++; // segment_start = segment_end; // continue; // } // // // calculate k-removals // for (int krems = 1; krems < n_in_segment && krems <= k; ++krems) { // // remval is the best reduction of naviasity when using krems breaks // int remval = 0; // // // TODO: jak to zrobić lepiej niż wykładniczo // // newsegment.push_back(remval); // } // newsegment.push_back() // // bestdeletes.push_back(newsegment); // } // for (int i = 0; i < cleaned_n; ++i) { // printf("%c", cleaned_expr[i]); // } // printf("\n"); long long expnum = 1; for (int i = 0; i < total_n; ++i) { expnum *= 2; } long long max_naviasity = compute_naviasity(); long long min_naviasity = max_naviasity; for (long long i = 1; i < expnum; ++i) { for (int j = 0; j < 50; ++j) { deletions[j] = false; } long long xcopy = i; int d_idx = 0; int yess = 0; while(xcopy > 0) { deletions[d_idx] = xcopy%2; if (deletions[d_idx]) { yess++; } d_idx++; xcopy /= 2; } if (yess != k) { continue; } long long nav = compute_naviasity(); // DEBUG START // printf("result for: "); // xcopy = i; // while(xcopy > 0) { // printf("%d", xcopy%2); // xcopy /= 2; // } // printf(" : %d\n", nav); // DEBUG END if (nav < min_naviasity) { min_naviasity = nav; } } printf("%lld\n", min_naviasity); return 0; } long long compute_naviasity() { int total_naviasity = 0; int prev_on_level[30]; for(int i = 0; i < 30; ++i){ prev_on_level[i] = 0; } int seen_n = 0; int current_level = 0; for (int i = 0; i < cleaned_n; ++i) { if (cleaned_expr[i] == '(') { current_level++; } else if (cleaned_expr[i] == 'B') { for(int i = 0; i < 30; ++i){ prev_on_level[i] = 0; } current_level = 0; } else if (cleaned_expr[i] == 'N') { if (deletions[seen_n]) { // treat as 'B' for(int i = 0; i < 30; ++i){ prev_on_level[i] = 0; } current_level = 0; } else { total_naviasity += prev_on_level[current_level]+1; prev_on_level[current_level] ++; } seen_n += 1; } else if (cleaned_expr[i] == ')') { // reset current streak prev_on_level[current_level] = 0; current_level--; if (current_level < 0) { current_level = 0; } else { total_naviasity += prev_on_level[current_level]+1; prev_on_level[current_level] ++; } } } return total_naviasity; } |