当前位置: 首页 > 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;
}
 

http://www.xdnf.cn/news/577279.html

相关文章:

  • MCU开发学习记录19* - CAN学习与实践(HAL库) - 定时传输、触发传输和请求传输(轮询与中断实现) -STM32CubeMX
  • Python 代码缩进与结构化编程:从基础到风格规范
  • Robotaxi新消息密集释放,量产元年来临谁在领跑?
  • [Java恶补day2] 49. 字母异位词分组
  • 【SW】从3D模型导出dxf图纸
  • 【算法专题十五】BFS解决最短路问题
  • 04_Prometheus监控docker容器(4)
  • 智慧社区新防线:华奥系AI技术如何让夏季安防“零隐患”
  • 如何在JavaScript中将数值转换为字符串并赋值给数组——以RuoYi-Vue项目为例
  • Redis Cluster动态扩容:架构原理与核心机制解析
  • 航电系统之航点跟踪系统篇
  • C++(27): 标准库 <iterator>
  • 逆向音乐APP:Python爬虫获取音乐榜单 (1)
  • Podman(Pod Manager)简介
  • 嵌入式STM32学习——串口USART 2.1(串口发送字符串和字符)
  • 应用分享 | 软件定义架构如何满足GNSS模拟测试的开放性需求?
  • JDK9~17语法新特性全览:Java语言的持续进化
  • Python数据可视化高级实战之二——热力图绘制探究
  • C++ 输出流格式控制
  • 起重的技术
  • wd软件安装
  • origin绘图之【如何将横坐标/x设置为文字、字母形式】
  • 升级SpringBoot2到3导致的WebServices升级
  • 数字化,一个泛化的概念
  • 使用Mathematica生成随机曼陀罗花
  • vue3请求设置responseType: ‘blob‘,导致失败后获取不到返回信息
  • 基于vue框架的动漫论坛g2392(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • ISO 26262-5 硬件验证
  • Python雷达图实战教程:从入门到精通
  • 磁盘分区与挂载——笔记