原题: HDU 3362 http://acm.hdu.edu.cn/showproblem.php?pid=3362

开始准备贪心搞,结果发现太难了,一直都没做出来。后来才知道要用状压DP。

题意:题目给出n(n <= 18)个点的二维坐标,并说明某些点是被固定了的,其余则没固定,要求添加一些边,使得还没被固定的点变成固定的,可见题目中的图形sample。

由于n很小,而且固定点的顺序没有限制,所以需要用状态压缩DP。

注意:
1.当一个没固定的点和两个固定了的点连接后,该点就被(间接)固定了(三角形的稳定性质)
2.被固定的点还可以用来固定别的点

因此,对于当前需要固定的点,在已经是固定状态的点中选出两个距离当前点最小的,这就保证了局部最优,从起始状态开始转移,最后判断能否到达最终目标状态就可以了。

代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <cmath>
  5. #include <algorithm>
  6. #define Mod 1000000007
  7. using namespace std;
  8. #define N 100007
  9.  
  10. struct Point
  11. {
  12. double x,y;
  13. int f;
  14. }p[];
  15. double dp[<<];
  16. int unfix[];
  17. double dis[];
  18. int n;
  19.  
  20. double Dis(int i,int j)
  21. {
  22. Point ka = p[i];
  23. Point kb = p[j];
  24. return (double)sqrt((ka.x-kb.x)*(ka.x-kb.x)+(ka.y-kb.y)*(ka.y-kb.y));
  25. }
  26.  
  27. double Fixit(int state,int tofix)
  28. {
  29. int i = ,j;
  30. int tmp = state;
  31. memset(dis,,sizeof(dis));
  32. while(i < n)
  33. {
  34. if(tmp & ) //已固定点
  35. {
  36. unfix[i] = ;
  37. dis[i] = Dis(tofix,i);
  38. }
  39. else
  40. unfix[i] = ;
  41. i++;
  42. tmp >>= ;
  43. }
  44. double mini_1 = Mod;
  45. int tag = -;
  46. for(i=;i<n;i++) //选第一个点
  47. {
  48. if(!unfix[i]) //fixed
  49. {
  50. if(dis[i] < mini_1)
  51. {
  52. mini_1 = dis[i];
  53. tag = i;
  54. }
  55. }
  56. }
  57. double mini_2 = Mod;
  58. for(i=;i<n;i++) //选第二个点
  59. {
  60. if(i == tag) //选过
  61. continue;
  62. if(!unfix[i])
  63. {
  64. if(dis[i] < mini_2)
  65. mini_2 = dis[i];
  66. }
  67. }
  68. if(mini_1+mini_2 >= Mod)
  69. return -;
  70. return mini_1+mini_2;
  71. }
  72.  
  73. int main()
  74. {
  75. int i,j;
  76. int Na;
  77. while(scanf("%d",&n)!=EOF && n)
  78. {
  79. int S = ;
  80. Na = (<<n)-;
  81. for(i=;i<n;i++)
  82. {
  83. scanf("%lf%lf%d",&p[i].x,&p[i].y,&p[i].f);
  84. if(p[i].f)
  85. S |= (<<i);
  86. }
  87. for(i=;i<=Na;i++)
  88. dp[i] = Mod;
  89. dp[S] = ;
  90. for(i=S;i<Na;i++)
  91. {
  92. if(dp[i] == Mod)
  93. continue;
  94. for(j=;j<n;j++) //选一个unfix的点固定
  95. {
  96. if(i & (<<j)) //已fix,跳过
  97. continue;
  98. double delta = Fixit(i,j);
  99. if(delta == -)
  100. continue;
  101. else //更新固定完这个点后的最少花费
  102. dp[i|(<<j)] = min(dp[i|(<<j)],dp[i]+delta);
  103. }
  104. }
  105. if(dp[Na] == Mod)
  106. puts("No Solution");
  107. else
  108. printf("%.6lf\n",dp[Na]);
  109. }
  110. return ;
  111. }

2014 Super Training #1 B Fix 状压DP的更多相关文章

  1. 2014 Super Training #7 C Diablo III --背包问题(DP)

    原题: ZOJ 3769 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3769 一个带有一些限制的背包问题. 假设在没有限 ...

  2. 2014 Super Training #10 D 花生的序列 --DP

    原题: FZU 2170 http://acm.fzu.edu.cn/problem.php?pid=2170 这题确实是当时没读懂题目,连样例都没想通,所以没做了,所以还是感觉这样散漫的做不好,有些 ...

  3. 2014 Super Training #8 C An Easy Game --DP

    原题:ZOJ 3791 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3791 题意:给定两个0-1序列s1, s2,操作t ...

  4. 【uoj#37/bzoj3812】[清华集训2014]主旋律 状压dp+容斥原理

    题目描述 求一张有向图的强连通生成子图的数目对 $10^9+7$ 取模的结果. 题解 状压dp+容斥原理 设 $f[i]$ 表示点集 $i$ 强连通生成子图的数目,容易想到使用总方案数 $2^{sum ...

  5. HDU 3362 Fix (状压DP)

    题意:题目给出n(n <= 18)个点的二维坐标,并说明某些点是被固定了的,其余则没固定,要求添加一些边,使得还没被固定的点变成固定的, 要求总长度最短. 析:由于这个 n 最大才是18,比较小 ...

  6. HDUOJ Clear All of Them I 状压DP

    Clear All of Them I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 122768/62768 K (Java/Oth ...

  7. ZOJ3802 Easy 2048 Again (状压DP)

    ZOJ Monthly, August 2014 E题 ZOJ月赛 2014年8月 E题 http://acm.zju.edu.cn/onlinejudge/showProblem.do?proble ...

  8. 【状压dp】cf906C. Party

    需要稍加分析结论:还有一些小细节 Arseny likes to organize parties and invite people to it. However, not only friends ...

  9. hdu 4778 Gems Fight! 状压dp

    转自wdd :http://blog.csdn.net/u010535824/article/details/38540835 题目链接:hdu 4778 状压DP 用DP[i]表示从i状态选到结束得 ...

随机推荐

  1. flask-uploads扩展的使用笔记

    涉及的flask扩展 flask-uploads flask的一个文件上传扩展, 提供了UploadSet这个概念 flask-wtf(中文) 很强大的表单的扩展 flask-bootstrap bo ...

  2. mongodb学习4---索引

    1,mongodb的性能分析 db.active.find({id:'sdfasdf6jh67j353g346hkfgh6'}).explain('executionStats') "mil ...

  3. 选择使用c语言编写的phalcon框架

    使用这个框架,我总结了如下几点考虑 1.这个框架速度快.纯c语言编写的框架,速度都比php框架快,省去了中间环节.当然,使用它不仅仅是性能考虑.因为如果为了解决php性能问题,完全可以有很多种方式,不 ...

  4. 推荐轻量友好的.NET测试断言工具Shouldly

    Shouldly是一个轻量的断言(Assertion)框架,用于补充.NET框架下的测试工具.Shouldly将焦点放在当断言失败时如何简单精准的给出很好的错误信息. Shouldly在GitHub的 ...

  5. Eclipse下Android开发的问题:Failed to install AndroidPhone.apk on device 'emulator-5554': timeout 解决办法

    在window->preferences->Android->DDMS->ADB connection time out (ms): 将这个值设置的大一些,默认为5000,我设 ...

  6. eclipse导入svn项目,项目却没有svn的标记

    现象: eclipse(已经装有svn插件)导入svn项目,项目没有svn的标记. 原因: 1.可能是由于你的svn eclipse插件,也就是subclipse,与svn的客户端版本不匹配. 解决 ...

  7. [C/C++] VS 2015 C++ 插件

    Visual Studio2015 Community一些必备插件 ReSharper C++ 各种语言版本的代码重构,代码风格,代码修正功能,非常强大,可惜不是免费的,不过好在可以破解呢. Vias ...

  8. 讲解Canvas中的一些重要方法

    Canvas所提供的各种方法根据功能来看大致可以分为几类: 第一是以drawXXX为主的绘制方法: 第二是以clipXXX为主的裁剪方法: 第三是以scale.skew.translate和rotat ...

  9. CSS 包含选择器(九)

    一.包含选择器 包含选择器中前后两部分之间以空格隔开,根据左侧选择符指定的祖先元素,然后在该元素下寻找匹配右侧的选择侧符的下级元素 定义包含选择器时,必须保证在HTML结构中第一个对象能够包含第二个对 ...

  10. spring boot 1.4.1 with jsp file sample

    <!--pom.xml--> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=" ...