codeforces 8C
题意:
给
定
n
个
物
品
,
第
i
个
物
品
的
坐
标
为
(
x
i
,
y
i
)
,
你
的
起
点
坐
标
为
(
x
s
,
y
s
)
。
给定n个物品,第i个物品的坐标为(x_i,y_i),你的起点坐标为(x_s,y_s)。
给定n个物品,第i个物品的坐标为(xi,yi),你的起点坐标为(xs,ys)。
现
在
要
将
所
有
物
品
全
部
放
回
起
点
,
每
次
手
中
拿
的
物
品
数
量
不
能
超
过
2
个
。
现在要将所有物品全部放回起点,每次手中拿的物品数量不能超过2个。
现在要将所有物品全部放回起点,每次手中拿的物品数量不能超过2个。
从
一
个
位
置
到
另
外
一
个
位
置
花
费
的
时
间
为
距
离
的
平
方
。
问
最
少
时
间
。
从一个位置到另外一个位置花费的时间为距离的平方。问最少时间。
从一个位置到另外一个位置花费的时间为距离的平方。问最少时间。
题解:
d p [ i [ 代 表 i 状 态 花 费 的 最 少 时 间 。 dp[i[代表i状态花费的最少时间。 dp[i[代表i状态花费的最少时间。
- d p [ i ∣ 1 < < j ∣ 1 < < k ] = m i n ( d p [ i ∣ 1 < < j ∣ 1 < < k ] , d p [ i ] + d i s [ 0 ] [ j + 1 ] + d i s [ j + 1 ] [ k + 1 ] + d i s [ k + 1 ] [ 0 ] ) dp[i | 1<<j | 1<<k] = min(dp[i | 1<<j | 1<<k] ,dp[i]+dis[0][j+1]+dis[j+1][k+1]+dis[k+1][0]) dp[i∣1<<j∣1<<k]=min(dp[i∣1<<j∣1<<k],dp[i]+dis[0][j+1]+dis[j+1][k+1]+dis[k+1][0])
#include <bits\stdc++.h>
using namespace std;
int x[25], y[25], dis[25][25], path[1<<24];
int dp[1<<24];
int main() {
int n;
cin >> x[0] >> y[0] >> n;
for(int i = 1 ; i <= n ; i++){
cin >> x[i] >> y[i];
}
for(int i = 0 ; i <= n ; i++){
for(int j = 0 ; j <= n ; j++){
dis[i][j] = (x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
}
}
memset(dp, 0x3f, sizeof(dp));
dp[0] = 0;
for(int i = 0 ; i < (1<<n)-1 ; i++){
if(dp[i] < 0x3f3f3f3f){
for(int j = 0 ; j < n ; j++){
if(!(i>>j & 1)){
for(int k = j ; k < n ; k++){
if(!(i>>k & 1)){
if(dp[i | 1<<j | 1<<k] > dp[i]+dis[0][j+1]+dis[j+1][k+1]+dis[k+1][0]){
dp[i | 1<<j | 1<<k] = dp[i]+dis[0][j+1]+dis[j+1][k+1]+dis[k+1][0];
path[i | 1<<j | 1<<k] = i;
}
}
}
break;
}
}
}
}
cout << dp[(1<<n)-1] << endl;;
cout << 0;
for(int i = (1<<n)-1 ; i > 0 ; i = path[i]){
for(int j = i^path[i] ; j > 0 ; j -= j & -j){
cout << ' ' << (int)(log(j&-j)/log(2)+1e-8+1);
}
cout << ' ' << 0;
}
return 0;
}