洛谷-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
",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