Clear All of Them I(HDU 3920状压dp)

题意:给有2*n个敌人的位置,枪在(0,0)位置,一次能消灭两个敌人,耗费能量为枪到一个敌人,由这个敌人再到另个敌人的的距离和,求消灭所有敌人最小耗费能量。

分析:一次枚举状态的两位即可

#include <map>

#include <set>

#include <list>

#include <cmath>

#include <queue>

#include <stack>

#include <cstdio>

#include <vector>

#include <string>

#include <cctype>

#include <complex>

#include <cassert>

#include <utility>

#include <cstring>

#include <cstdlib>

#include <iostream>

#include <algorithm>

using namespace std;

typedef pair<int,int> PII;

typedef long long ll;

#define lson l,m,rt<<1

#define pi acos(-1.0)

#define rson m+1,r,rt<<11

#define All 1,N,1

#define read freopen("in.txt", "r", stdin)

#define N 1<<20

const ll  INFll = 0x3f3f3f3f3f3f3f3fLL;

const int INF= 0x7ffffff;

const int mod =  1000000007;

double dp[N],d[150][150];

int n;

struct point{

    double x,y;

}p[25],s;

double dis(point a,point b){

    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));

}

int main()

{

    int t,n;

    scanf("%d",&t);

   for(int e=1;e<=t;++e)

    {

        int i,j,k;

        scanf("%lf%lf",&s.x,&s.y);

        scanf("%d",&n);

        for(i=0;i<2*n;i++)

            scanf("%lf%lf",&p[i].x,&p[i].y);

        for(i=0;i<2*n;i++)

        {

            d[i][2*n]=dis(s,p[i]);

            for(j=0;j<2*n;j++)

                d[i][j]=d[j][i]=dis(p[i],p[j]);

        }

        int cas=(1<<(2*n))-1;

        for(i=0;i<=cas;i++)

            dp[i]=INF;

        dp[0]=0;

        for(i=0;i<=cas;i++){

            if(dp[i]==INF)continue;

                for(j=0;j<2*n;j++)

                    if((i&(1<<j))==0)

                        break;

                for(k=j+1;k<2*n;k++)

                {

                    if(i&(1<<k))

                        continue;

                    double tmp=min(d[j][2*n],d[k][2*n]);

                    tmp+=d[j][k];

                    int tcase=i+(1<<j)+(1<<k);

                    dp[tcase]=min(dp[tcase],dp[i]+tmp);

                }

        }

        printf("Case #%d: %.2lf\n",e,dp[cas]);

    }

    return 0;

}

  

你可能感兴趣的:(clear)