1 条题解
-
0
小数据暴力+大数据贪心 = 95分
#include <bits/stdc++.h> using namespace std; const int MAXN = 1005; int n, k; struct Point { double x, y; } p[MAXN + 5]; double dis[MAXN + 5][MAXN + 5]; namespace case1 { // n<=9 枚举所有方案 double ans; int id[10], path[10]; void solve() { for (int i = 1; i <= n; i++) id[i] = i; ans = 1000 * 2e7; do { if (id[1] != k) continue; double now = 0; for (int i = 2; i <= n; i++) now += dis[id[i]][id[i - 1]]; if (now < ans) { ans = now; for (int i = 1; i <= n; i++) path[i] = id[i]; } } while (next_permutation(id + 1, id + n + 1)); for (int i = 1; i <= n; i++) cout << path[i] << " "; cout << "\n"; } } namespace case2 { // n<=18 状压 dp double f[1 << 20][20]; // f[sta][last]: 走完了 sta 这些点,最后一次走的是 last 时的最短路径 int path[1 << 20][20]; vector<int> ans; void solve() { for (int sta = 0; sta <= (1 << n) - 1; sta++) for (int i = 1; i <= n; i++) { f[sta][i] = 1000 * 2e7; path[sta][i] = -1; } for (int sta = 0; sta <= (1 << n) - 1; sta++) { if ((sta & (1 << (k - 1))) == 0) continue; // 无效状态 if (sta == (1 << (k - 1))) { f[sta][k] = 0; path[sta][k] = 0; continue; } for (int last = 1; last <= n; last++) { if ((sta & (1 << (last - 1))) == 0) continue; int nxtSta = sta - (1 << (last - 1)); for (int pre = 1; pre <= n; pre++) { if (nxtSta & (1 << (pre - 1)) == 0) continue; if (f[nxtSta][pre] + dis[pre][last] < f[sta][last]) { f[sta][last] = f[nxtSta][pre] + dis[pre][last]; path[sta][last] = pre; } } } } int ansSta = (1 << n) - 1; int ansLast = 1; for (int i = 1; i <= n; i++) if (f[ansSta][i] < f[ansSta][ansLast]) ansLast = i; ans.push_back(ansLast); while (path[ansSta][ansLast] != 0) { ans.push_back(path[ansSta][ansLast]); int temp = ansLast; ansLast = path[ansSta][ansLast]; ansSta -= (1 << (temp - 1)); } for (int i = ans.size() - 1; i >= 0; i--) cout << ans[i] << " "; cout << "\n"; } } namespace case3 { // 贪心不停走最近的 bool vis[MAXN + 5]; vector<int> ans; void solve() { for (int i = 1; i <= n; i++) vis[i] = false; ans.push_back(k); vis[k] = true; int now = k; for (int i = 1; i <= n - 1; i++) { int nxt = -1; for (int j = 1; j <= n; j++) { if (vis[j]) continue; if (nxt == -1 || dis[now][j] < dis[now][nxt]) nxt = j; } ans.push_back(nxt); vis[nxt] = true; } for (int i = 0; i < ans.size(); i++) cout << ans[i] << " "; cout << "\n"; } } int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> n; k = 0; for (int i = 1; i <= n; i++) { cin >> p[i].x >> p[i].y; if (k == 0 || p[i].y > p[k].y) k = i; } for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) dis[i][j] = sqrt((p[i].x - p[j].x) * (p[i].x - p[j].x) + (p[i].y - p[j].y) * (p[i].y - p[j].y)); if (n <= 9) case1::solve(); else if (n <= 18) case2::solve(); else case3::solve(); return 0; }
- 1
信息
- ID
- 1236
- 时间
- 1000ms
- 内存
- 1024MiB
- 难度
- 10
- 标签
- 递交数
- 55
- 已通过
- 0
- 上传者