HDU 3920Clear All of Them I(状压DP)
题目是说有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)这就可以过了
下面从前往后美剧上一个状态时递推时我是用的队列存的所有状态,其实枚举过去也是可以的
//#pragma comment(linker,"/STACK:102400000,102400000")
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 1e9
#define inf (-((LL)1<<40))
#define lson k<<1, L, mid
#define rson k<<1|1, mid+1, R
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
#define FOPENIN(IN) freopen(IN, "r", stdin)
#define FOPENOUT(OUT) freopen(OUT, "w", stdout)
template<class T> T CMP_MIN(T a, T b) { return a < b; }
template<class T> T CMP_MAX(T a, T b) { return a > b; }
template<class T> T MAX(T a, T b) { return a > b ? a : b; }
template<class T> T MIN(T a, T b) { return a < b ? a : b; }
template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } //typedef __int64 LL;
//typedef long long LL;
const int MAXN = ;
const int MAXM = ;
const double eps = 1e-;
//const LL MOD = 1000000007; int T, N;
typedef double Point[];
Point st, p[MAXN];
double dis[MAXN][MAXN], d[MAXN], dp[<<]; double calc(Point a, Point b)
{
double x = a[] - b[];
double y = a[] - b[];
return sqrt(x*x + y*y);
} void getDis()
{
for(int i=;i<N;i++)
{
d[i] = calc(st, p[i]);
for(int j=i+;j<N;j++)
{
dis[j][i] = dis[i][j] = calc(p[i], p[j]);
}
}
} int main()
{
int t = ;
scanf("%d", &T);
while(T--)
{
scanf("%lf %lf", &st[], &st[]);
scanf("%d", &N);
N <<= ;
for(int i=;i<N;i++)
scanf("%lf %lf", &p[i][], &p[i][]);
getDis();
dp[] = ;
for(int i=;i<(<<N);i++) dp[i] = INF;
queue<int>q;
q.push();
while(!q.empty())
{
int now = q.front(); q.pop();
int f=, r;
while( now & (<<f) && f < N)
f++;
for(r = f + ; r < N; r ++ )
if(!(now & (<<r)))
{
int next = now | (<<f) | (<<r);
double minDis = MIN(d[f], d[r]) + dis[f][r];
if( fabs(dp[next] - INF) < eps )
{
q.push(next);
dp[next] = dp[now] + minDis;
}
else if( dp[now] + minDis < dp[next] )
dp[next] = dp[now] + minDis;
}
}
printf("Case #%d: %.2lf%\n", ++t, dp[(<<N)-]);
}
return ;
}
HDU 3920Clear All of Them I(状压DP)的更多相关文章
- HDU 5067 Harry And Dig Machine(状压DP)(TSP问题)
题目地址:pid=5067">HDU 5067 经典的TSP旅行商问题模型. 状压DP. 先分别预处理出来每两个石子堆的距离.然后将题目转化成10个城市每一个城市至少经过一次的最短时间 ...
- HDU 1565 - 方格取数(1) - [状压DP][网络流 - 最大点权独立集和最小点权覆盖集]
题目链接:https://cn.vjudge.net/problem/HDU-1565 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32 ...
- HDU 1074:Doing Homework(状压DP)
http://acm.hdu.edu.cn/showproblem.php?pid=1074 Doing Homework Problem Description Ignatius has just ...
- hdu 2167 方格取数 【状压dp】(经典)
<题目链接> 题目大意: 给出一些数字组成的n*n阶矩阵,这些数字都在[10,99]内,并且这个矩阵的 3<=n<=15,从这个矩阵中随机取出一些数字,在取完某个数字后,该数 ...
- HDU 6149 Valley Numer II(状压DP)
题目链接 HDU6149 百度之星复赛的题目……比赛的时候并没有做出来. 由于低点只有15个,所以我们可以考虑状压DP. 利用01背包的思想,依次考虑每个低点,然后枚举每个状态. 在每个状态里面任意枚 ...
- HDU 4917 Permutation(拓扑排序 + 状压DP + 组合数)
题目链接 Permutation 题目大意:给出n,和m个关系,每个关系为ai必须排在bi的前面,求符合要求的n的全排列的个数. 数据规模为n <= 40,m <= 20. 直接状压DP空 ...
- HDU 2809 God of War (状压DP)
God of War Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- 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 ...
- HDU 3681 Prison Break 越狱(状压DP,变形)
题意: 给一个n*m的矩阵,每个格子中有一个大写字母,一个机器人从‘F’出发,拾取所有的开关‘Y’时便能够越狱,但是每走一格需要花费1点能量,部分格子为充电站‘G’,每个电站只能充1次电.而且部分格子 ...
- HDU 5418 Victor and World(状压DP+Floyed预处理)
Victor and World Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/131072 K (Java/Other ...
随机推荐
- PopupWindow+ListView
1. 获取打到数据 for (int i = 0; i < iocOutMakeMaterialSubmit.data.size(); i++) { dataListPopupWindow.ad ...
- BZOJ 1787 紧急集合
LCA.注意细节. #include<iostream> #include<cstdio> #include<cstring> #include<algori ...
- AutoGenSystem
#coding=utf-8 # # AutoGenSystem # 声明: # 该软件主要是为了解决Android系统更新时,由于版本很多,管理起来复杂,容易出错,于是采用软件 # 自动对系统软件进行 ...
- matplotlib 绘制柱状图的几个例子
1 error bar #!/usr/bin/env python # a bar plot with errorbars import numpy as np import matplotlib.p ...
- (转)每天一个Linux命令(6):mv
mv命令是move的缩写,可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. 1.命令格式: mv [选项] 源文件或目 ...
- css overflow:hidden无效解决办法
解决方案:只需要在设定overflow:hidden层加入定位即可 position:relative;left:0px;top:0px
- gcc-4.8.3安装,gdb-7.6安装
gdb用法: http://blog.chinaunix.net/uid-26548237-id-3435525.html gdb-7.6.tar.gz: (官网下载:http://ftp.gnu. ...
- Bootstrap学习之路(3)---列表组件
列表是几乎所有网站都会用到的一个组件,正好bootstrap也给我们提供了这个组件的样式,下面我给大家简单介绍一下bootstrap中的列表组件的用法! 首先,重提一下引用bootstrap的核心文件 ...
- VB6.0编程笔记——(2)开发环境准备&学习前导入
工欲善其事必先利其器,着手开始学习写代码之前,我们需要先准备好需要用到的工具.这篇文章会教大家部署好环境,同时会告知前期我们需要知道的一点内容(可以不用特别理解,只要记住用法就行,后续会深入展开介绍) ...
- 十六进制字符串转化成字符串输出HexToStr(Delphi版、C#版)
//注意:Delphi2010以下版本默认的字符编码是ANSI,VS2010的默认编码是UTF-8,delphi版得到的字符串须经过Utf8ToAnsi()转码才能跟C#版得到的字符串显示结果一致. ...