hdu 3920 Clear All of Them I

状态压缩DP

主要是由于每次从最右边的1开始找,所以一般的正推可能会导致产生很多冗余状态

记忆话搜索的话会好不少


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int n;
struct Point
{
    double x, y;
    double dis;
}node[21];
double f[1<<20];
double map[21][21];
double dist(int i, int j)
{
    return sqrt((node[i].x - node[j].x) * (node[i].x - node[j].x)
                + (node[i].y - node[j].y) * (node[i].y - node[j].y));
}
double dp(int depth)
{
    if(f[depth] >= 0)  return f[depth];

    int val = depth;
    int pos = -1;
    f[depth] = 1e12;//初始化为正无穷
    for(int i = 0; val; val >>= 1, i++)
    {
        if(val & 1)
        {
            if(pos == -1)  pos = i;
            else
            {
                f[depth] = min(f[depth], dp(depth - (1 << pos) - (1 << i))
                               + node[pos].dis + map[pos][i]);
                f[depth] = min(f[depth], dp(depth - (1 << pos) - (1 << i))
                               + node[i].dis + map[pos][i]);
            }
        }
    }
    return f[depth];
}
int main()
{
    int cas = 1;
    int T;
    double sx, sy;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%lf%lf", &sx, &sy);
        scanf("%d", &n);
        n <<= 1;
        for(int i = 0; i < n; i++)
           scanf("%lf%lf", &node[i].x, &node[i].y);
        node[n].x = sx;
        node[n].y = sy;

        for(int i = 0; i < n; i++)
           node[i].dis = dist(i,n);


        for(int i = 0; i < n; i++)
          for(int j = i + 1; j < n; j++)
          map[i][j] = map[j][i] = dist(i,j);

        int st = 1 << n;
        for(int i = 0; i < st; i++)  f[i] = -1;
        f[0] = 0.0;
        printf("Case #%d: %0.2lf\n",cas++,dp((st-1)));
    }
    return 0;
}



你可能感兴趣的:(hdu 3920 Clear All of Them I)