当前位置: 首页 > news >正文

《P1433 吃奶酪》

题目描述

房间里放着 n 块奶酪。一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在 (0,0) 点处。

输入格式

第一行有一个整数,表示奶酪的数量 n。

第 2 到第 (n+1) 行,每行两个实数,第 (i+1) 行的实数分别表示第 i 块奶酪的横纵坐标 xi​,yi​。

输出格式

输出一行一个实数,表示要跑的最少距离,保留 2 位小数。

输入输出样例

输入 #1复制

4
1 1
1 -1
-1 1
-1 -1

输出 #1复制

7.41

说明/提示

数据规模与约定

对于全部的测试点,保证 1≤n≤15,∣xi​∣,∣yi​∣≤200,小数点后最多有 3 位数字。

提示

对于两个点 (x1​,y1​),(x2​,y2​),两点之间的距离公式为 (x1​−x2​)2+(y1​−y2​)2​。


2022.7.13:新增加一组 Hack 数据。

代码实现:

#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;

const int N = 15;
const double INF = 1e18;
double x[N], y[N];
double dist[N][N]; // dist[i][j] 表示奶酪i到奶酪j的距离(i,j从0开始,0为原点?不,原点单独处理)
// 原点是起点,奶酪从0到n-1编号,共n个奶酪,状态压缩n位对应0~n-1
double dp[1 << N][N]; // dp[state][u]:已访问state中的奶酪,最后位于奶酪u时的最短距离

int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> x[i] >> y[i];
    }

    // 计算原点到各奶酪的距离,以及奶酪间的距离
    double origin_dist[N]; // 原点到奶酪i的距离
    for (int i = 0; i < n; i++) {
        origin_dist[i] = sqrt(x[i] * x[i] + y[i] * y[i]);
        for (int j = 0; j < n; j++) {
            double dx = x[i] - x[j];
            double dy = y[i] - y[j];
            dist[i][j] = sqrt(dx * dx + dy * dy);
        }
    }

    // 初始化DP数组:初始时未访问任何奶酪,从原点出发到奶酪u
    memset(dp, 0x3f, sizeof(dp));
    for (int u = 0; u < n; u++) {
        dp[1 << u][u] = origin_dist[u]; // 访问奶酪u,距离为原点到u的距离
    }

    // 遍历所有状态
    for (int state = 1; state < (1 << n); state++) {
        for (int u = 0; u < n; u++) {
            if (!(state & (1 << u))) continue; // u未被访问,跳过
            for (int v = 0; v < n; v++) {
                if (state & (1 << v)) continue; // v已被访问,跳过
                int new_state = state | (1 << v);
                // 从奶酪u到奶酪v,更新new_state下v的距离
                if (dp[new_state][v] > dp[state][u] + dist[u][v]) {
                    dp[new_state][v] = dp[state][u] + dist[u][v];
                }
            }
        }
    }

    // 最终结果:遍历所有奶酪后,从任意奶酪u返回原点的最短距离
    double min_total = INF;
    int full_state = (1 << n) - 1;
    for (int u = 0; u < n; u++) {
        min_total = min(min_total, dp[full_state][u] + origin_dist[u]);
    }

    printf("%.2f\n", min_total);
    return 0;
}
 

相关文章:

  • 高阶数据结构——红黑树实现
  • 【ffmpeg】ffprobe基本用法
  • 85本适合AI入门的人工智能书籍合集免费资源
  • 物业后勤小程序源码介绍
  • Python Seaborn 高级可视化指南
  • Veo 3 可以生成视频,并附带配乐
  • Azure 应用服务中的异常处理、日志记录和通知:综合指南
  • 如何使用Java生成pdf报告
  • Linux——PostgreSQL数据库日常维护
  • .NET外挂系列:4. harmony 中补丁参数的有趣玩法(上)
  • SD绘画指南
  • 机器学习第二十讲:网格搜索 → 像尝试所有密码组合找最佳解锁方式
  • 第九届电子信息技术与计算机工程国际学术会议(EITCE 2025)
  • 初识Linux · 五种IO模型和非阻塞IO
  • 探索Puter:一个基于Web的轻量级“云操作系统”
  • 2025.05.21华为暑期实习机考真题解析第一题
  • 31-35【动手学深度学习】深度学习硬件
  • Nginx核心服务
  • Typescript学习教程,从入门到精通,TypeScript 面向对象编程指南:抽象类、接口及其应用知识点及案例代码(9)
  • 论文阅读:Auto-Encoding Variational Bayes
  • 中国建筑招标投标网官网/南昌网站优化公司
  • 网站建设网站定制/百度手机助手官网
  • 中国太平保险集团官方网站/口碑营销的案例
  • 云南网站开发建设/百度登录入口