2014辽宁省赛 Picking Cabbage 状压dp

Description

Once, Doraemon and  Nobita planted a farm with cabbage. One night their farm was stealed by Takeshi Gian. Takeshi Gian picked away most of the cabbage, but left some cabbage in the farm. Then he left a note to Doraemon and  Nobita, telling them the coordinate of the cabbage still in the farm. As soon as Doraemon and  Nobita get the note, they run out to save their cabbage.

Doraemon has a warp gate in his house that can send them to a cabbage which they wanted to. Then they should run from one cabbage to another to get them. Since they wanted to get all the cabbage as soon as possible, they should run the shortest way. Can you calculate the shortest path that they should run

Input

There are multiple test cases. The first line is a positive integer stands for the number of test cases.
The first line of each test case is a positive integer N(1<=N<=15) stands for the number of cabbage that Takeshi Gian left.
Then N following lines each has two integer xi, yi, (0<=xi,yi<=100) stands for the coordinate of the cabbage.

Output

Output the shortest path of getting all the cabbage in one line keeping two decimal places.
Doraemon and  Nobita just wanted to get all of the cabbage as soon as possible, so, don't bother about their path of getting back home.

Sample Input

2
3
0 0
0 1
0 2
3
0 0
0 1
1 0

Sample Output

2.00
2.00






#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<climits>
using namespace std;
const double eps=1e-6;
struct POINT
{
    int x;
    int y;
};
int n;
double d[1<<16][16];
POINT point[16];
double distant(int a,int b)
{
    return sqrt(pow(point[a].x-point[b].x,2)+pow(point[a].y-point[b].y,2));
}
double dp(int x,int y)
{

    if(d[x][y]>eps)return d[x][y];
    d[x][y]=9999;
    for(int i=0;i<n;i++)
    {
        if(i==y)continue;
        if((x>>i)%2)
        {
            d[x][y]=min(d[x][y],dp(x-(1<<y),i)+distant(y,i));
        }
    }
    if(fabs(d[x][y]-9999)<eps)d[x][y]=0;
    return d[x][y];
}
int main()
{
    //freopen("in.txt","r",stdin);
    int t;
    while(cin>>t)
    {
        while(t--)
        {
            cin>>n;
            memset(d,0,sizeof(d));
            memset(point,0,sizeof(point));
            for(int i=0;i<n;i++)
            {
                cin>>point[i].x>>point[i].y;
            }
            double mx=9999;
            for(int i=0;i<n;i++)
            {
                mx=min(dp((1<<(n+1))-1,i),mx);
            }
            printf("%.2f\n",mx);
        }
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值