#include #include #include #include #include using namespace std; using vi = vector; using vvi = vector; const int INF = 0x7fffffff; struct location { int x, y; int pokemon; }; vector pokestops; int dist(int i, int j) { return std::abs(pokestops[i].x - pokestops[j].x) + std::abs(pokestops[i].y - pokestops[j].y); } int dist_to_home(int i) { return std::abs(pokestops[i].x) + std::abs(pokestops[i].y); } int get_bit(int x, int pos) { return 1 & (x >> pos); } int bits_count(int x) { int cnt = 0; for (int i = 0; i < 30; ++i) { cnt += get_bit(x, i); } return cnt; } int main() { int n; cin >> n; map pokemon_to_index; for (int i = 0; i < n; ++i) { pokestops.emplace_back(); cin >> pokestops.back().x >> pokestops.back().y; string pokemon_name; cin >> pokemon_name; pokemon_to_index.emplace(pokemon_name, pokemon_to_index.size()); pokestops.back().pokemon = pokemon_to_index[pokemon_name]; } int m = static_cast(pokemon_to_index.size()); vvi integers_by_num_bits(m + 1); for (int x = 0; x < (1 << m); ++x) { integers_by_num_bits[bits_count(x)].push_back(x); } vvi dp(1 << m, vi(n, INF)); for (int i = 0; i < n; ++i) { dp[0][i] = dist_to_home(i); } for (int len = 0; len < m; ++len) { for (int state : integers_by_num_bits[len]) { for (int curr_pos = 0; curr_pos < n; ++curr_pos) { if (dp[state][curr_pos] == INF) continue; for (int next_pos = 0; next_pos < n; ++next_pos) { int p = pokestops[next_pos].pokemon; if (get_bit(state, p)) continue; int next_state = state | (1 << p); dp[next_state][next_pos] = min(dp[next_state][next_pos], dp[state][curr_pos] + dist(curr_pos, next_pos)); } } } } int ans = INF; for (int i = 0; i < n; ++i) { ans = min(ans, dp[(1 << m) - 1][i] + dist_to_home(i)); } cout << ans << endl; return 0; }