• [luogu p1433] 吃奶酪


    传送门

    题面

    题目描述

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

    输入输出格式

    输入格式

    第一行一个正整数 (n)。 接下来每行 (2) 个实数,表示第i块奶酪的坐标。 两点之间的距离公式为 (sqrt{(x_1-x_2)^2+(y_1-y_2)^2})

    输出格式

    一个数,表示要跑的最少距离,保留 (2) 位小数。

    输入输出样例

    输入样例 #1

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

    输出样例 #1

    7.41
    

    说明

    (1leq nleq 15)

    分析

    数据范围暴露一切:这道题用状压dp
    这道题的状压dp过于简单,我并不想多说,,

    代码

    /*
     * @Author: crab-in-the-northeast 
     * @Date: 2020-02-22 23:12:58 
     * @Last Modified by:   crab-in-the-northeast 
     * @Last Modified time: 2020-02-22 23:12:58  
     */
    //插件出锅了……Last Modified time应该是2020-02-23 00:58分钟左右,不知道他咋想的,,
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #undef y1
    
    int n;
    const int maxn = 25;
    double dp[25][40005];
    
    struct cheese {
        double x;
        double y;
    }a[maxn];
    
    double getdis(double x1,double y1,double x2,double y2) {
        return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
    }
    
    double min(double a,double b) {
        return a < b ? a : b;
    }
    
    int main() {
        memset(dp,127,sizeof(dp));//初始化dp为无穷大(memset小技巧)
        scanf("%d",&n);
        for(int i = 1; i <= n; i++) scanf("%lf %lf",&a[i].x,&a[i].y);
    
        for(int s = 1; s <= (1 << n) - 1; s++) {
            for(int i = 1; i <= n; i++) {
                if(s & (1 << (i - 1))) {
                    if(s == (1 << (i-1))) {
                            dp[i][s] = 0;
                            continue;
                    }
                    for(int j = 1; j <= n; j++) {
                        if(i != j && s & (1 << (j - 1))) {
                            dp[i][s] = min(dp[i][s],dp[j][s - (1 << (i - 1))] + getdis(a[i].x,a[i].y,a[j].x,a[j].y));
                        }
                    }
                }
            }
        }
        //以上都是状压板子,这里不多说。
    
        double ans = 1008610086;
        for(int i = 1; i <= n; i++) ans = min(ans,dp[i][(1 << n) - 1]+getdis(a[i].x,a[i].y,a[0].x,a[0].y));
        printf("%.2lf
    ",ans);
        return 0;
        //好吧算下来我好想啥都没说……
    }
    

    评测结果

    AC 100R30954388

  • 相关阅读:
    markdown模式的一些语法
    markdown模式的一些语法
    微信小游戏跳一跳外挂教程(安卓版)
    微信小游戏跳一跳外挂教程(安卓版)
    仿百度地图上拉下滑抽屉盒
    仿百度地图上拉下滑抽屉盒
    验证码倒计时的注册页面
    验证码倒计时的注册页面
    1430 素数判定
    2834 斐波那契数
  • 原文地址:https://www.cnblogs.com/crab-in-the-northeast/p/luogu-p1433.html
Copyright © 2020-2023  润新知