zoukankan      html  css  js  c++  java
  • HDU 3362 Fix(状压DP)

    Fix

    Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 916    Accepted Submission(s): 309


    Problem Description
    There are a few points on a plane, and some are fixed on the plane, some are not. We want to connect these points by some sticks so that all the points are fixed on the plane. Of course, we want to know the minimum length of the sum of the sticks.

    As in the images, the black points are fixed on the plane and red ones are not, which need to be fixed by sticks.
    All the points in the left image have been fixed. But the middle one is not, which we need add one stick to fix those four points (the right image shows that stick). Triangle is steady, isn’t it?


     

    Input
    The input consists of multiply test cases. The first line of each test case contains one integer, n (1 <= n <= 18), which is the number of points. The next n lines, each line consists of three integers, x, y, c (0 <= x, y < 100). (x, y) indicate the coordinate of one point; c = 1 indicates this point is fixed; c = 0 indicates this point is not fixed. You can assume that no two points have the same coordinate.
    The last test case is followed by a line containing one zero, which means the end of the input.
     

    Output
    Output the minimum length with six factional digits for each test case in a single line. If you cannot fix all the points, then output “No Solution”.
     

    Sample Input
    4 0 0 1 1 0 1 0 1 0 1 1 0 3 0 0 1 1 1 0 2 2 0 0
     

    Sample Output
    4.414214 No Solution
     

    Source

    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <set>
    #include <algorithm>
    #define LL long long
    using namespace std;
    const int MAXN = 20;
    const double INF = 100000000.0;
    struct Node
    {
        int x, y;
    }Point[MAXN];
    int fix[MAXN], start, target, N;
    double dis[MAXN], dp[1<<21];
    double Dis(int a, int b)
    {
        double x = (double)(Point[a].x - Point[b].x);
        double y = (double)(Point[a].y - Point[b].y);
        return sqrt(x * x + y * y);
    }
    double solve(int s, int x)
    {
        int m = 0;
        for(int i=0;i<N;i++) if(s & (1 << i))
           dis[m++] = Dis(i, x);
        sort(dis, dis + m);
       // cout << m << endl;
        if(m < 2) return -1;
        double ans = dis[0] + dis[1];
        return ans;
    }
    int main()
    {
        while(scanf("%d", &N)!=EOF && N)
        {
            start = target = 0;
            for(int i=0;i<N;i++)
            {
                scanf("%d%d%d", &Point[i].x, &Point[i].y, &fix[i]);
                if(fix[i]) start |= (1 << i);
                target |= (1 << i);
            }
            for(int i=0;i<=target;i++) dp[i] = INF;
            dp[start] = 0;
            for(int s=start;s<=target;s++)
            {
                if(dp[s] == INF) continue;
                for(int i=0;i<N;i++)
                {
                    if(!(s & (1 << i)))
                    {
                        double res = solve(s, i);
                        //cout << s << ' ' << i << ' ' << res << endl;
                        if(res >= 0) dp[s|(1<<i)] = min(dp[s|(1<<i)], dp[s] + res);
                       // cout << dp[s] << ' ' << dp[s|(1<<i)] << endl;
                    }
                }
            }
            if(dp[target] >= INF) printf("No Solution
    ");
            else printf("%.6lf
    ", dp[target]);
        }
        return 0;
    }


  • 相关阅读:
    ListView具有多种item布局——实现微信对话列
    CSDN 2013年度博客之星评选——分享几张厦门杭州的美图
    不做旁观者,给博主最有力的支持——博客之星评选,期待您的支持,谢谢路过的朋友投上您宝贵的一票
    Android应用中使用及实现系统“分享”接口
    android手势创建及识别
    JSON数据源的多值参数实现
    葡萄城报表本地设计器
    如何设计带查询条件的报表
    巧用SQL语句补足不完全数据报表
    表格数据分组报表
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/7131956.html
Copyright © 2011-2022 走看看