#include <iostream> using namespace std; // 1. sprawdzić czy w ogóle musi jechać do biura. Jeśli nie, no to trywialne // 2. zakładamy że musi. Ustawiamy wyjazd na zero i powrót na n i zbijamy z dwóch stron? // CHCEMY ZMINIMALIZOWAĆ LICZBĘ TRÓJEK W SEGMENCIE PODRÓŻÓWO-PRACOWYM // bo to są jedyne "zmarnowane" segmenty - wszystkie inne idą na podbicie spotkań albo na trzaskanie zadanek // czyli wiemy tak naprawdę, jakiej długości PP segment jest nam potrzebny, i rozszerzamy go o tyle ile jest w nim 3 // np. musimy odbyć 5 spotkań enum blocktype { STACJO = 1, ZDALNE = 2, WOLNE = 3, TOTALMEETS = 4, }; int upto[8001][5]; int values(int start, int end, int typ) { if (end < start) { return 0; } if (start == 0) { return upto[end][typ]; } return upto[end][typ] - upto[start-1][typ]; } int main() { int totalblocks, missable_meets, commute_time; string s; cin >> totalblocks >> missable_meets >> commute_time; cin >> s; char c = s[0]; upto[0][c-48] = 1; upto[0][TOTALMEETS] = upto[0][ZDALNE] + upto[0][STACJO]; for (int i = 1; i < totalblocks; ++i) { upto[i][0] = upto[i-1][0]; upto[i][1] = upto[i-1][1]; upto[i][2] = upto[i-1][2]; char c = s[i]; upto[i][c-48] += 1; upto[i][TOTALMEETS] = upto[i][ZDALNE] + upto[i][STACJO]; } int total_meets = upto[totalblocks-1][ZDALNE] + upto[totalblocks-1][STACJO]; int mandatory_meets = max(0, total_meets - missable_meets); int best_res = totalblocks - mandatory_meets; // cout << "STACJOS\n"; // for (int i = 0; i < totalblocks; ++i) { // cout << upto[i][STACJO] << " "; // } // cout << endl; // cout << "ZDALNES\n"; // for (int i = 0; i < totalblocks; ++i) { // cout << upto[i][ZDALNE] << " "; // } // cout << endl; // cout << "TOTALMS\n"; // for (int i = 0; i < totalblocks; ++i) { // cout << upto[i][TOTALMEETS] << " "; // } // cout << endl; // cout << "======================================================================\n"; // opt 1: nigdzie nie jedziemy bo wszystkie spotkania stacjo można ominąć if (upto[totalblocks-1][STACJO] <= missable_meets) { cout << best_res << endl; return 0; } int bestest_score = -1; int last_drive = totalblocks - (commute_time * 2) - 1; // last possible slot to drive to work for (int drive_1_start = 0; drive_1_start <= last_drive; ++drive_1_start) { for (int drive_2_start = drive_1_start + commute_time + 1; drive_2_start <= totalblocks - commute_time; ++drive_2_start) { // cout << "===============================================================================\n"; int work_start_idx = drive_1_start + commute_time; // cout << "DRIVE 1: " << drive_1_start << " -> " << drive_1_start + commute_time - 1 << endl; // cout << "WORK : " << work_start_idx << " -> " << drive_2_start - 1 << endl; // cout << "DRIVE 2: " << drive_2_start << " -> " << drive_2_start + commute_time - 1 << endl; int stacjo_meets = values(work_start_idx, drive_2_start - 1, TOTALMEETS); int meets_left = max(mandatory_meets - stacjo_meets, 0); int possible_zdalne = values(0, drive_1_start - 1, ZDALNE) + values(drive_2_start + commute_time, totalblocks - 1, ZDALNE); // cout << "Stacjo meets : " << stacjo_meets << endl; // cout << "Meets left : " << meets_left << endl; // cout << "Possible zdalne: " << possible_zdalne << endl; if (possible_zdalne < meets_left) { continue; } int result = drive_1_start + (totalblocks - drive_2_start - commute_time) - meets_left; if (result > bestest_score) { bestest_score = result; } // cout << "RESULT: " << result << endl; /* * 0 -> drive_1_start zdalnie * drive_1_start -> drive_1_start + commute_time zmarnowane * work_start_idx -> drive_2_start praca * drive_2_start -> drive_2_start + commute_time zmarnowane * drive_2_start + commute_time -> END zdalnie */ } } cout << bestest_score << endl; 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 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 | #include <iostream> using namespace std; // 1. sprawdzić czy w ogóle musi jechać do biura. Jeśli nie, no to trywialne // 2. zakładamy że musi. Ustawiamy wyjazd na zero i powrót na n i zbijamy z dwóch stron? // CHCEMY ZMINIMALIZOWAĆ LICZBĘ TRÓJEK W SEGMENCIE PODRÓŻÓWO-PRACOWYM // bo to są jedyne "zmarnowane" segmenty - wszystkie inne idą na podbicie spotkań albo na trzaskanie zadanek // czyli wiemy tak naprawdę, jakiej długości PP segment jest nam potrzebny, i rozszerzamy go o tyle ile jest w nim 3 // np. musimy odbyć 5 spotkań enum blocktype { STACJO = 1, ZDALNE = 2, WOLNE = 3, TOTALMEETS = 4, }; int upto[8001][5]; int values(int start, int end, int typ) { if (end < start) { return 0; } if (start == 0) { return upto[end][typ]; } return upto[end][typ] - upto[start-1][typ]; } int main() { int totalblocks, missable_meets, commute_time; string s; cin >> totalblocks >> missable_meets >> commute_time; cin >> s; char c = s[0]; upto[0][c-48] = 1; upto[0][TOTALMEETS] = upto[0][ZDALNE] + upto[0][STACJO]; for (int i = 1; i < totalblocks; ++i) { upto[i][0] = upto[i-1][0]; upto[i][1] = upto[i-1][1]; upto[i][2] = upto[i-1][2]; char c = s[i]; upto[i][c-48] += 1; upto[i][TOTALMEETS] = upto[i][ZDALNE] + upto[i][STACJO]; } int total_meets = upto[totalblocks-1][ZDALNE] + upto[totalblocks-1][STACJO]; int mandatory_meets = max(0, total_meets - missable_meets); int best_res = totalblocks - mandatory_meets; // cout << "STACJOS\n"; // for (int i = 0; i < totalblocks; ++i) { // cout << upto[i][STACJO] << " "; // } // cout << endl; // cout << "ZDALNES\n"; // for (int i = 0; i < totalblocks; ++i) { // cout << upto[i][ZDALNE] << " "; // } // cout << endl; // cout << "TOTALMS\n"; // for (int i = 0; i < totalblocks; ++i) { // cout << upto[i][TOTALMEETS] << " "; // } // cout << endl; // cout << "======================================================================\n"; // opt 1: nigdzie nie jedziemy bo wszystkie spotkania stacjo można ominąć if (upto[totalblocks-1][STACJO] <= missable_meets) { cout << best_res << endl; return 0; } int bestest_score = -1; int last_drive = totalblocks - (commute_time * 2) - 1; // last possible slot to drive to work for (int drive_1_start = 0; drive_1_start <= last_drive; ++drive_1_start) { for (int drive_2_start = drive_1_start + commute_time + 1; drive_2_start <= totalblocks - commute_time; ++drive_2_start) { // cout << "===============================================================================\n"; int work_start_idx = drive_1_start + commute_time; // cout << "DRIVE 1: " << drive_1_start << " -> " << drive_1_start + commute_time - 1 << endl; // cout << "WORK : " << work_start_idx << " -> " << drive_2_start - 1 << endl; // cout << "DRIVE 2: " << drive_2_start << " -> " << drive_2_start + commute_time - 1 << endl; int stacjo_meets = values(work_start_idx, drive_2_start - 1, TOTALMEETS); int meets_left = max(mandatory_meets - stacjo_meets, 0); int possible_zdalne = values(0, drive_1_start - 1, ZDALNE) + values(drive_2_start + commute_time, totalblocks - 1, ZDALNE); // cout << "Stacjo meets : " << stacjo_meets << endl; // cout << "Meets left : " << meets_left << endl; // cout << "Possible zdalne: " << possible_zdalne << endl; if (possible_zdalne < meets_left) { continue; } int result = drive_1_start + (totalblocks - drive_2_start - commute_time) - meets_left; if (result > bestest_score) { bestest_score = result; } // cout << "RESULT: " << result << endl; /* * 0 -> drive_1_start zdalnie * drive_1_start -> drive_1_start + commute_time zmarnowane * work_start_idx -> drive_2_start praca * drive_2_start -> drive_2_start + commute_time zmarnowane * drive_2_start + commute_time -> END zdalnie */ } } cout << bestest_score << endl; return 0; } |