HDU 3920   Clear All of Them I

题目是说有2n个敌人,现在可以发n枚炮弹,每枚炮弹可以(可以且仅可以)打两个敌人,每一枚炮弹的花费等于它所行进的距离,现在要消灭所有的敌人,问最少花费是多少(反正题意大概就是这样啦,知道怎么回事就好了,解释不清了)

一看到n<=10而且又是在DP专题里的,就知道这个显然是状压DP,由于有2n个敌人,所以状态表示由当前状态再打两个人来转移,

10000100表示打了这两个敌人的最小花费

所以状态的转移是由前往后递推的,假如当前状态是cur,上一个状态是last,应该满足存在i!=j有last&(1<<i)=0且last&(1<<j)=0且last | (1<<i)|(1<<j) = cur,由此来更新当前的状态cur,最后的答案就是DP[(1<<(2n)) - 1]

注意到上面我们是要枚举i和j的,所以这个的总复杂度就是20 * 20 * 2^20,这显然是会超时的, 所以需要优化

注意到如果存在两队人(a,b)(c,d)我们先打(a, b)再打(c, d)和先打(c,d)在打(a, b)是一样的,所以我们完全可以每次取last中最小的一位是0的与后面所有的0组合,这样不仅没有漏掉解,而且复杂度也将到了O(20 * 2^20)这就可以过了

下面从前往后美剧上一个状态时递推时我是用的队列存的所有状态,其实枚举过去也是可以的

  1. //#pragma comment(linker,"/STACK:102400000,102400000")
  2. #include <map>
  3. #include <set>
  4. #include <stack>
  5. #include <queue>
  6. #include <cmath>
  7. #include <ctime>
  8. #include <vector>
  9. #include <cstdio>
  10. #include <cctype>
  11. #include <cstring>
  12. #include <cstdlib>
  13. #include <iostream>
  14. #include <algorithm>
  15. using namespace std;
  16. #define INF 1e9
  17. #define inf (-((LL)1<<40))
  18. #define lson k<<1, L, mid
  19. #define rson k<<1|1, mid+1, R
  20. #define mem0(a) memset(a,0,sizeof(a))
  21. #define mem1(a) memset(a,-1,sizeof(a))
  22. #define mem(a, b) memset(a, b, sizeof(a))
  23. #define FOPENIN(IN) freopen(IN, "r", stdin)
  24. #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
  25. template<class T> T CMP_MIN(T a, T b) { return a < b; }
  26. template<class T> T CMP_MAX(T a, T b) { return a > b; }
  27. template<class T> T MAX(T a, T b) { return a > b ? a : b; }
  28. template<class T> T MIN(T a, T b) { return a < b ? a : b; }
  29. template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
  30. template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; }
  31.  
  32. //typedef __int64 LL;
  33. //typedef long long LL;
  34. const int MAXN = ;
  35. const int MAXM = ;
  36. const double eps = 1e-;
  37. //const LL MOD = 1000000007;
  38.  
  39. int T, N;
  40. typedef double Point[];
  41. Point st, p[MAXN];
  42. double dis[MAXN][MAXN], d[MAXN], dp[<<];
  43.  
  44. double calc(Point a, Point b)
  45. {
  46. double x = a[] - b[];
  47. double y = a[] - b[];
  48. return sqrt(x*x + y*y);
  49. }
  50.  
  51. void getDis()
  52. {
  53. for(int i=;i<N;i++)
  54. {
  55. d[i] = calc(st, p[i]);
  56. for(int j=i+;j<N;j++)
  57. {
  58. dis[j][i] = dis[i][j] = calc(p[i], p[j]);
  59. }
  60. }
  61. }
  62.  
  63. int main()
  64. {
  65. int t = ;
  66. scanf("%d", &T);
  67. while(T--)
  68. {
  69. scanf("%lf %lf", &st[], &st[]);
  70. scanf("%d", &N);
  71. N <<= ;
  72. for(int i=;i<N;i++)
  73. scanf("%lf %lf", &p[i][], &p[i][]);
  74. getDis();
  75. dp[] = ;
  76. for(int i=;i<(<<N);i++) dp[i] = INF;
  77. queue<int>q;
  78. q.push();
  79. while(!q.empty())
  80. {
  81. int now = q.front(); q.pop();
  82. int f=, r;
  83. while( now & (<<f) && f < N)
  84. f++;
  85. for(r = f + ; r < N; r ++ )
  86. if(!(now & (<<r)))
  87. {
  88. int next = now | (<<f) | (<<r);
  89. double minDis = MIN(d[f], d[r]) + dis[f][r];
  90. if( fabs(dp[next] - INF) < eps )
  91. {
  92. q.push(next);
  93. dp[next] = dp[now] + minDis;
  94. }
  95. else if( dp[now] + minDis < dp[next] )
  96. dp[next] = dp[now] + minDis;
  97. }
  98. }
  99. printf("Case #%d: %.2lf%\n", ++t, dp[(<<N)-]);
  100. }
  101. return ;
  102. }

HDU 3920Clear All of Them I(状压DP)的更多相关文章

  1. HDU 5067 Harry And Dig Machine(状压DP)(TSP问题)

    题目地址:pid=5067">HDU 5067 经典的TSP旅行商问题模型. 状压DP. 先分别预处理出来每两个石子堆的距离.然后将题目转化成10个城市每一个城市至少经过一次的最短时间 ...

  2. HDU 1565 - 方格取数(1) - [状压DP][网络流 - 最大点权独立集和最小点权覆盖集]

    题目链接:https://cn.vjudge.net/problem/HDU-1565 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32 ...

  3. HDU 1074:Doing Homework(状压DP)

    http://acm.hdu.edu.cn/showproblem.php?pid=1074 Doing Homework Problem Description Ignatius has just ...

  4. hdu 2167 方格取数 【状压dp】(经典)

    <题目链接> 题目大意: 给出一些数字组成的n*n阶矩阵,这些数字都在[10,99]内,并且这个矩阵的  3<=n<=15,从这个矩阵中随机取出一些数字,在取完某个数字后,该数 ...

  5. HDU 6149 Valley Numer II(状压DP)

    题目链接 HDU6149 百度之星复赛的题目……比赛的时候并没有做出来. 由于低点只有15个,所以我们可以考虑状压DP. 利用01背包的思想,依次考虑每个低点,然后枚举每个状态. 在每个状态里面任意枚 ...

  6. HDU 4917 Permutation(拓扑排序 + 状压DP + 组合数)

    题目链接 Permutation 题目大意:给出n,和m个关系,每个关系为ai必须排在bi的前面,求符合要求的n的全排列的个数. 数据规模为n <= 40,m <= 20. 直接状压DP空 ...

  7. HDU 2809 God of War (状压DP)

    God of War Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. HDU 4026 Unlock the Cell Phone 状压dp(类似TSP)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4026 Unlock the Cell Phone Time Limit: 6000/3000 MS ...

  9. HDU 3681 Prison Break 越狱(状压DP,变形)

    题意: 给一个n*m的矩阵,每个格子中有一个大写字母,一个机器人从‘F’出发,拾取所有的开关‘Y’时便能够越狱,但是每走一格需要花费1点能量,部分格子为充电站‘G’,每个电站只能充1次电.而且部分格子 ...

  10. HDU 5418 Victor and World(状压DP+Floyed预处理)

    Victor and World Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java/Other ...

随机推荐

  1. POJ 1201 Intervals (差分约束系统)

    题意 在区间[0,50000]上有一些整点,并且满足n个约束条件:在区间[ui, vi]上至少有ci个整点,问区间[0, 50000]上至少要有几个整点. 思路 差分约束求最小值.把不等式都转换为&g ...

  2. activiti 引擎 数据库设计说明书

    1.结构设计 1.1.    逻辑结构设计 Activiti使用到的表都是ACT_开头的. ACT_RE_*: ’RE’表示repository(存储),RepositoryService接口所操作的 ...

  3. scala学习笔记(9):Scala函数(2)

    1 指令式编程&函数式编程 指令式:imperative 风格编程.指令式风格,是你常常使用像 Java,C++和 C 这些语言里用的风格,一次性发出一个指令式的命令,用循环去枚举,并经常改变 ...

  4. ecshop 改变sitemap.xml的位置

    大家知道ECSHOP默认的sitemap.xml文件是放置在data文件夹中的,但是这不利于GOOGLE的抓取.我们必须把sitemap.xml文件放置在根目录下 在admin/sitemap.php ...

  5. bash 的漏洞,你们中招了吗?

    http://threatpost.com/major-bash-vulnerability-affects-linux-unix-mac-os-x 检测: $ env x='(){:;}; echo ...

  6. php 获取指定日期所在月份的最后一天

    本文引用来自 http://hi.baidu.com/yflife/item/fd00ef142c5967fcdceeca84 php 获取指定月最后一天: <?phpfunction gett ...

  7. 垂直的TextView

    所先声明一下这个类是我从网上找到的一篇文章,只是保留并没有侵权的意思. public class TextViewVertical extends View { public static final ...

  8. js仿手机端九宫格登录功能

    js仿手机端九宫格登录功能 最近闲来无事把以前无聊时开发的小东西拿出来和大家分享下,写的不好的请指出,我会及时修改.谢谢. 功能及方法逻辑都注释在代码中.所以麻烦大家直接看代码. 效果如下: 话不多说 ...

  9. linux下的加减运算

    命令: echo rep 如果你有些编程方面的概念,最有意思的是用gdb,它可以进行进制转换,浮点数运算,数据类型占用字节数等等,很方便. (gdb) p 2+5$21 = 7(gdb) p 2/5$ ...

  10. Excel导出问题(导出时不去掉前面的0)(转)

    最简单的方法是:在数字前面加'符号.即代码里添加: "'" 以下均是网上搜集到的其他解答: 一.代码如下: style="mso-number-format:'/@';& ...