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): 1037    Accepted Submission(s): 349

    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

    题目大意:把动点固定最少需要多长的木棒。

    题解:状态压缩+dp

    #include <iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    double inf=100000000000.0;
    double dis[300000];
    int n;
    int start,target;
    struct node
    {
        double x,y;
        bool fix;
    }p[20];
    double cal(int a,int b)
    {
      return sqrt((double)((p[a].x-p[b].x)*(p[a].x-p[b].x)+(p[a].y-p[b].y)*(p[a].y-p[b].y)));
    }
    double work(int k,int t)
    {
        double dis[20];
        int l=0;
        for(int i=0;i<n;i++)
         if (k&(1<<i))   dis[l++]=cal(i,t); //判断第i个点是否固定
        if (l<2) return -1;
        sort(dis,dis+l);//sort的第一个参数首地址,第二个参数尾地址,排序范围为“[,)”
        return dis[0]+dis[1];
    }
    int main()
    {
       while(~scanf("%d",&n))
       {
           if (n==0) break;
           start=0;
           target=0;
           for(int i=0;i<n;i++)
           {
              scanf("%lf%lf%d",&p[i].x,&p[i].y,&p[i].fix);
              start=start|(p[i].fix<<i);
              target=target|(1<<i);
           }
           for(int i=0;i<=target;i++) dis[i]=inf;
           dis[start]=0;
           for(int k=start;k<=target;k++)
           {
    //if (dis[k]==inf) continue; 这句最好加上
    for(int i=0;i<n;i++) if ( !(k&(1<<i)) )//判断第i个点是否可以移动,如果可以继续做 { double res=work(k,i); if(res>0) dis[k|(1<<i)]=min(dis[k|(1<<i)],dis[k]+res); } } if (dis[target]==inf) printf("No Solution "); else printf("%.6lf ",dis[target]); } return 0; }
  • 相关阅读:
    R vs Python:构建data.frame、读取csv与统计描述
    R语言学习笔记:使用reshape2包实现整合与重构
    Python学习笔记:lambda表达式
    Python学习笔记:startswith & endswith 判断开头结尾是否为指定字符串
    Python学习笔记:一手漂亮的Python函数
    电信行业数据挖掘分析
    Oracle学习笔记:实现select top N的方法
    Oracle学习笔记:ORA-22992 cannot use LOB locators selected from remote tables
    Linux学习笔记:ls和ll命令
    vb常用命名空间
  • 原文地址:https://www.cnblogs.com/stepping/p/6289225.html
Copyright © 2011-2022 走看看