HDU Clear All of Them I(状态压缩+DP+记忆搜索)
来源:互联网 发布:中草药软件 编辑:程序博客网 时间:2024/06/11 02:13
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 122768/62768 K (Java/Others)
Total Submission(s): 1556 Accepted Submission(s): 509
Total Submission(s): 1556 Accepted Submission(s): 509
Problem Description
Acmers have been the Earth Protector against the evil enemy for a long time, now it’s your turn to protect our home.
There are 2 * n enemies in the map. Your task is to clear all of them with your super laser gun at the fixed position (x, y).
For each laser shot, your laser beam can reflect 1 times (must be 1 times), which means it can kill 2 enemies at one time. And the energy this shot costs is the total length of the laser path.
For example, if you are at (0, 0), and use one laser shot kills the 2 enemies in the order of (3, 4), (6, 0), then the energy this shot costs is 5.0 + 5.0 = 10. 00.
Since there are 2 * n enemies, you have to shot n times to clear all of them. For each shot, it is you that select two existed enemies and decide the reflect order.
Now, telling you your position and the 2n enemies’ position, to save the energy, can you tell me how much energy you need at least to clear all of them?
Note that:
> Each enemy can only be attacked once.
> All the positions will be unique.
> You must attack 2 different enemies in one shot.
> You can’t change your position.
There are 2 * n enemies in the map. Your task is to clear all of them with your super laser gun at the fixed position (x, y).
For each laser shot, your laser beam can reflect 1 times (must be 1 times), which means it can kill 2 enemies at one time. And the energy this shot costs is the total length of the laser path.
For example, if you are at (0, 0), and use one laser shot kills the 2 enemies in the order of (3, 4), (6, 0), then the energy this shot costs is 5.0 + 5.0 = 10. 00.
Since there are 2 * n enemies, you have to shot n times to clear all of them. For each shot, it is you that select two existed enemies and decide the reflect order.
Now, telling you your position and the 2n enemies’ position, to save the energy, can you tell me how much energy you need at least to clear all of them?
Note that:
> Each enemy can only be attacked once.
> All the positions will be unique.
> You must attack 2 different enemies in one shot.
> You can’t change your position.
Input
The first line contains a single positive integer T( T <= 100 ), indicates the number of test cases.
For each case:
There are 2 integers x and y in the first line, which means your position.
The second line is an integer n(1 <= n <= 10), denote there are 2n enemies.
Then there following 2n lines, each line have 2 integers denote the position of an enemy.
All the position integers are between -1000 and 1000.
For each case:
There are 2 integers x and y in the first line, which means your position.
The second line is an integer n(1 <= n <= 10), denote there are 2n enemies.
Then there following 2n lines, each line have 2 integers denote the position of an enemy.
All the position integers are between -1000 and 1000.
Output
For each test case: output the case number as shown and then print a decimal v, which is the energy you need at least to clear all of them (round to 2 decimal places).
Sample Input
20 016 03 00 021 02 1-1 0-2 0
Sample Output
Case #1: 6.00Case #2: 4.41
第一次写的状态压缩的题目,首先这个题目有贪心性质。说明如下:假设当我们以最小代价消灭完全部敌人的状态是S,从S中去除两个同一次消灭的敌人,剩下的状态必定也是最小的,可以反证法证明。现在假设一直退回到初始状态,还剩三点O,A,B。因为AB之间的距离是固定的,所以要想三点连线距离最小肯定要从OA,OB中选最小的。利用贪心可以优化程序。
题目中的状态转移过程:当前状态中随便去除任意两点可以得到上一个状态,从中选最小代价的,复杂度是20*20*2^20,需要记忆化搜索还有上面说的贪心性质降低复杂度。
程序中对点按照距离原点的距离排序,利用贪心,去掉了一个for循环。
#include <iostream>#include <cmath>#include <algorithm>using namespace std;typedef struct node{int x;int y;void input(){scanf("%d%d",&x,&y);}}Point;Point st,pt[21];int n;double dp[1<<21];double dis[21][21];double min(double a,double b){return a<b?a:b;}double eval_dis(Point a,Point b){double x = (a.x-b.x)*1.0;double y = (a.y-b.y)*1.0;return sqrt(x*x+y*y);}bool cmp(Point a,Point b){return eval_dis(a,st) < eval_dis(b,st);}double Dp(int state){if(dp[state] != 0x7fffffff)return dp[state];if(state == 0) dp[0] = 0.0;//初始状态else{int i = 0;for(i = 0;i < 20; i++)//这里用到了贪心思想,即选最近的点 if((1<<i) & state) break;for(int j = i+1;j < 2*n; j++){if(((1<<j)&state)){dp[state] = min(Dp(state-(1<<j)-(1<<i))+dis[i][j],dp[state]); }}}return dp[state];}int main(){int T,ca=0; scanf("%d",&T); while(T--) { ca++; st.input(); scanf("%d",&n); for(int i=0;i<2*n;i++) { pt[i].input(); } sort(pt,pt+2*n,cmp); for(i=0;i<2*n;i++){ for(int j=i+1;j<2*n;j++){ dis[i][j] = eval_dis(pt[i],st)+eval_dis(pt[i],pt[j]); }}printf("Case #%d: ",ca); for(i=0;i<(1<<2*n);i++) dp[i] = 0x7fffffff; printf("%.2f\n",Dp((1<<(2*n))-1)); }return 0;}
Sample Output
Case #1: 6.00Case #2: 4.41
0 0
- HDU Clear All of Them I(状态压缩+DP+记忆搜索)
- hdu 3920 Clear All of Them I (状态压缩DP)
- HDU--3920[Clear All of Them I] 状态压缩DP或模拟退火
- HDU 3920 Clear All of Them I 状态压缩DP 2011 Multi-University Training Contest 9 - Host by BJTU
- HDU3920:Clear All of Them I(状态压缩)
- hdu 3920 Clear All of Them I 状态压缩 动态规划
- HDU 3920 Clear All of Them I 状压DP
- hdu 3920 Clear All of Them I
- HDU 3920 Clear all of them I
- hdu3920 Clear All of Them I
- hdu 3921 Clear All of Them II
- hdu 4778 Gems Fight!【状态压缩,记忆化搜索dp】
- hdu4753 状态压缩dp博弈(记忆化搜索写法)
- hdu 4778 Gems Fight!(记忆化搜索+状态压缩)
- hdu 4628 Pieces(状态压缩+记忆化搜索)
- UVA 11600 - Masud Rana(状态压缩DP+记忆化搜索)
- uva 10651 Pebble Solitaire(dp,状态压缩,记忆化搜索)
- UVA 1252 Twenty Questions 状态压缩dp 记忆化搜索
- 随机化快速排序
- javascript中的this小结
- A. Forgotten Episode(水题)
- hdu 4111 Alice and Bob(博弈)
- poj 1422 最小路径覆盖
- HDU Clear All of Them I(状态压缩+DP+记忆搜索)
- 个人对多线程的总结
- Android单元测试jUnit
- 防止进程重新启动-keepalived源码解析
- java内存管理
- Hduoj3874 【离线+树状数组】
- 2014-11-8Android学习------Android抽屉效果的实现案例--------动画Animation学习篇
- 构建高性能Web站点(修订版)笔记
- JSP九大内置对象