洛谷-P1433 吃奶酪

洛谷-P1433 吃奶酪

原题链接:https://www.luogu.com.cn/problem/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

说明/提示

1≤n≤15。

C++代码

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

double x[16],y[16],f[16][1<<16];

double dis(int a, int b) {
    return sqrt(pow(x[a]-x[b],2)+pow(y[a]-y[b],2));
}

int main() {
    int n,s,i,j;
    double ans=-1;
    cin>>n;
    for(i=1;i<=n;++i)
        cin>>x[i]>>y[i];
    memset(f,127,sizeof(f));    // double无穷大赋值方式
    for(s=1;s<=(1<<n)-1;++s)
        for(i=1;i<=n;++i) {
            if((s&(1<<(i-1)))==0)   // 第i位为0
                continue;
            if(s==(1<<(i-1))) {
                f[i][s]=0;
                continue;
            }
            for(j=1;j<=n;++j) {
                if((s&(1<<(j-1)))==0||i==j)
                    continue;
                f[i][s]=min(f[i][s],f[j][s-(1<<(i-1))]+dis(i,j));
            }
        }
    for(i=1;i<=n;++i)
        f[i][(1<<n)-1]+=dis(0,i);
    for(i=1;i<=n;++i)
        if(ans==-1||ans>f[i][(1<<n)-1])
            ans=f[i][(1<<n)-1];
    printf("%.2f\n",ans);
    return 0;
}

题解

移位运算符将其左侧的值按其右侧的位数移动:

  • <<向左移动并在右端添加零。
  • >>右移,如果value是无符号类型,则加0,如果是有符号类型,则扩展最高位(保留符号)。

2<<4 == 32

-8 >> 3 == -1

简单的位运算:

a<<1 == a*2

a>>1 == a/2

1<<a == 2^a

((1<<(k-1)&s)) == 第k位为0

猜你喜欢

转载自www.cnblogs.com/yuzec/p/12928762.html