Submission #1283165

#TimeUsernameProblemLanguageResultExecution timeMemory
1283165abc123Train (APIO24_train)C++20
0 / 100
35 ms12644 KiB
#include <bits/stdc++.h> using namespace std; struct Train { int x, y, a, b, c; }; struct State { int planet, time, meals_mask; long long cost; bool operator>(const State &other) const { return cost > other.cost; } }; long long solve(int N, int M, int W, vector<int> T, vector<int> X, vector<int> Y, vector<int> A, vector<int> B, vector<int> C, vector<int> L, vector<int> R) { vector<Train> trains(M); for (int i = 0; i < M; i++) { trains[i] = {X[i], Y[i], A[i], B[i], C[i]}; } // Meals time intervals and total required meals // Precompute all meals and their time windows // DP Dijkstra state space: // State: (planet, time, meals_mask) // meals_mask - bitmask representing which meals have been taken // time up to max 10 as problem constraints say times ≤ 10 // // Since constraints are small (N,M,W ≤ 10), this approach is feasible. int max_time = 10; long long INF = 1e15; // cost[planet][time][meals_mask] = minimal cost to be here vector<vector<vector<long long>>> cost(N, vector<vector<long long>>(max_time+1, vector<long long>(1 << W, INF))); priority_queue<State, vector<State>, greater<State>> pq; // Start at planet 0, time 0, no meals taken cost[0][0][0] = 0; pq.push({0, 0, 0, 0}); auto meal_allowed_at = [&](int meal_idx, int t) { return (t >= L[meal_idx] && t <= R[meal_idx]); }; while (!pq.empty()) { State cur = pq.top(); pq.pop(); if (cost[cur.planet][cur.time][cur.meals_mask] < cur.cost) continue; // If reached planet N-1 with all meals taken if (cur.planet == N-1 && cur.meals_mask == (1 << W) - 1) { return cur.cost; } // Option 1: Take meals on the current planet if waiting (pay cost) // or eat free on a train (on train means time interval on any train route?) // Here, "waiting" means not on train, so if we do not move to next train yet, // we pay cost per meal on planet // Try taking any meal not yet taken, at current time if allowed for (int i = 0; i < W; i++) { if (!(cur.meals_mask & (1 << i)) && meal_allowed_at(i, cur.time)) { int new_mask = cur.meals_mask | (1 << i); // Can eat free on train route that covers this time - to check // but here we only store state on planet, meals taken here cost T[cur.planet] // So only pay if waiting on planet (no train now) long long new_cost = cur.cost + T[cur.planet]; if (new_cost < cost[cur.planet][cur.time][new_mask]) { cost[cur.planet][cur.time][new_mask] = new_cost; pq.push({cur.planet, cur.time, new_mask, new_cost}); } } } // Option 2: Take a train starting from current planet at or after current time // Transfer time is zero, so we can only board trains where start planet == cur.planet and departure time >= cur.time for (int i = 0; i < M; i++) { if (trains[i].x == cur.planet && trains[i].a >= cur.time) { // On train interval [A[i], B[i]] meals are free (if meal time in this range) // So take meals for free on this train on the time interval int new_mask = cur.meals_mask; for (int m = 0; m < W; m++) { if (!(new_mask & (1 << m))) { // If meal window overlaps train interval, can take free if (!(R[m] < trains[i].a || L[m] > trains[i].b)) { new_mask |= (1 << m); } } } long long new_cost = cur.cost + trains[i].c; if (new_cost < cost[trains[i].y][trains[i].b][new_mask]) { cost[trains[i].y][trains[i].b][new_mask] = new_cost; pq.push({trains[i].y, trains[i].b, new_mask, new_cost}); } } } // Option 3: Wait time forward if no train (increase time by 1) // Only if next time <= max_time if (cur.time < max_time) { // Waiting means pay per meal if eaten at this new time // But we do not know here if any meals taken at new time, so no cost added here except meals when taken if (cur.cost < cost[cur.planet][cur.time+1][cur.meals_mask]) { cost[cur.planet][cur.time+1][cur.meals_mask] = cur.cost; pq.push({cur.planet, cur.time+1, cur.meals_mask, cur.cost}); } } } // No way to reach planet N-1 with all meals return -1; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...