题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4281

Judges' response

Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
#### 问题描述
> The contest is running and the judges is busy watching the progress of the contest. Suddenly, N - 1 (N   You are asked to solve two problems:
>   1. At least how many judges should be sent so that they can serve all the contestants? (Because the judges have limited patience, each one of them cannot serve too many contestants.)
>   2. If there are infinite number of judges, how to assign the route for each judge so that the sum of their walking time is minimized? Each contestant i is reside in place (xi, yi), the judges are in place (x1, y1). Assuming the walking speed of the judge is 1.

输入

There are several test cases, Each case begin with two integer N, M(with the meaning in the above context, 2 <= N <= 16, 0 <= M <= 100000).

  Then N lines follow and line i will contain two numbers x, y(0 <= x, y <= 1000), indicating the coordinate of place i.

  Then another N lines follow and line i will contain numbers Ci(0 <= Ci <= 1000), indicating the time to solve contestant i's question. C1 will 0 as place 1 is for the judges.

  

  The distance between place i and place j is defined as ceil(sqrt((xi - xj) ^ 2 + (yi - yj) ^ 2)). (ceil means rounding the number up, e.g. ceil(4.1) = 5)

输出

  For each case, output two numbers. The first is the minimum number of judges for question 1. The second is the minimum sum of walking time for question 2.

  If it's impossible to serve all the contestants, please output -1 -1 instead.

样例输入

3 3

0 0

0 3

0 1

0

1

2

3 2

0 0

0 3

0 1

0

1

2

3 1

0 0

0 3

0 1

0

1

2

  

16 35

30 40

37 52

49 49

52 64

31 62

52 33

42 41

52 41

57 58

62 42

42 57

27 68

43 67

58 48

58 27

37 69

0

19

30

16

23

11

31

15

28

8

8

7

14

6

19

11

样例输出

1 6

2 8

-1 -1

8 467

题意

回答每个学生的问题需要ai的时间,每个助教的忍耐时间是m,一个助教接受的提问时间一定不能超过m,第一个问题是问最少需要多少个助教才能解决所有的学生的问题。第二个问题是说,给你助教的位置(第一个),和学生的位置,你现在有无限多的助教,这些助教解决完问题,最后要回到原先的点。问如何分配能使回答完所有的学生的问题之后所有的助教所走的路程总和最小。

题解

这题数据很小,可以考虑状压。

先把所有的总时间不超过m的学生的集合找出来,然后dp[i]表示接受状态为i的学生的问题需要最少的助教,j表示某个总和不超过m的子集,则有转移方程:dp[i]=min(dp[i],dp[i^j]+1)。

对于第二个问,我们也可以用第一个问题的方法来做dp2[i][0]表示走了状态为i的点,最后回到原来位置的最少路程,则,用这些子集(上个问就已经处理出来的那些集合),就能拼出走完所有的点所走的最短路程。

代码

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII; const int INF=0x3f3f3f3f;
const LL INFL=10000000000000000LL;
const double eps=1e-9; const double PI = acos(-1.0); //start---------------------------------------------------------------------- const int maxn=17; PII pt[maxn];
int arr[maxn];
int n,m;
VI vec;
int dp[1<<maxn];
int dp2[1<<maxn][maxn]; int dis(int i,int j) {
int x=pt[i].X-pt[j].X;
int y=pt[i].Y-pt[j].Y;
return ceil(sqrt(x*x+y*y));
} void tsp(int dp[][maxn]) {
rep(i,0,(1<<maxn)) rep(j,0,maxn) dp[i][j]=INF; dp[1][0]=0;
rep(i,2,(1<<n)) {
rep(j,0,n) {
if(!(i&(1<<j))) continue;
rep(k,0,n) {
if(k==j||(i&(1<<k))==0) continue;
dp[i][j]=min(dp[i][j],dp[i^(1<<j)][k]+dis(k,j));
}
}
}
rep(t,0,vec.sz()) {
int i=vec[t];
if((i&1)==0) continue;
rep(j,1,n) {
dp[i][0]=min(dp[i][0],dp[i][j]+dis(0,j));
}
}
} void init() {
vec.clear();
} int main() {
while(scf("%d%d",&n,&m)==2&&n) { init(); rep(i,0,n) scf("%d%d",&pt[i].X,&pt[i].Y);
rep(i,0,n) scf("%d",&arr[i]); rep(i,1,(1<<n)) {
int sum=0;
rep(j,0,n) {
if(!(i&(1<<j))) continue;
sum+=arr[j];
}
if(sum<=m) vec.pb(i);
} rep(i,0,(1<<n)) dp[i]=INF;
dp[0]=0;
rep(i,0,(1<<n)) {
rep(j,0,vec.sz()) {
if((i|vec[j])!=i) continue;
dp[i]=min(dp[i],dp[i^vec[j]]+1);
}
} int ans1=dp[(1<<n)-1]; if(ans1>=INF){
prf("-1 -1\n"); continue;
} tsp(dp2); rep(i,0,(1<<n)) dp[i]=INF;
dp[0]=0;
rep(i,0,(1<<n)) {
rep(j,0,vec.sz()) {
if((i|vec[j])!=i) continue;
dp[i]=min(dp[i],dp[i^vec[j]]+dp2[1|vec[j]][0]);
}
} int ans2=dp[(1<<n)-1]; prf("%d %d\n",ans1,ans2); }
return 0;
} //end-----------------------------------------------------------------------

HDU 4281 Judges' response 状压dp+多旅行商问题的更多相关文章

  1. hdu 3247 AC自动+状压dp+bfs处理

    Resource Archiver Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Ot ...

  2. hdu 2825 aC自动机+状压dp

    Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  3. HDU 5765 Bonds(状压DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5765 [题目大意] 给出一张图,求每条边在所有边割集中出现的次数. [题解] 利用状压DP,计算不 ...

  4. hdu 3681(bfs+二分+状压dp判断)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 思路:机器人从出发点出发要求走过所有的Y,因为点很少,所以就能想到经典的TSP问题.首先bfs预 ...

  5. hdu 4778 Gems Fight! 状压dp

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

  6. hdu 4856 Tunnels (bfs + 状压dp)

    题目链接 The input contains mutiple testcases. Please process till EOF.For each testcase, the first line ...

  7. HDU 4272 LianLianKan (状压DP+DFS)题解

    思路: 用状压DP+DFS遍历查找是否可行.假设一个数为x,那么他最远可以消去的点为x+9,因为x+1~x+4都能被他前面的点消去,所以我们将2进制的范围设为2^10,用0表示已经消去,1表示没有消去 ...

  8. HDU 3362 Fix (状压DP)

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

  9. HDU 3001 Travelling (状压DP,3进制)

    题意: 给出n<=10个点,有m条边的无向图.问:可以从任意点出发,至多经过同一个点2次,遍历所有点的最小费用? 思路: 本题就是要卡你的内存,由于至多可经过同一个点2次,所以只能用3进制来表示 ...

随机推荐

  1. 2019北航OO第一单元作业总结

    一.前三次作业内容分析总结 前言 前三次作业,我提交了三次,但是有效作业只有两次,最后一次作业没能实现多项式求导的基本功能因此无疾而终,反思留给后文再续,首先我介绍一下这三次作业,三次作业围绕着多项式 ...

  2. php如何实现统计一个数字在排序数组中出现的次数(代码)

    统计一个数字在排序数组中出现的次数. 博客 www.51msk.cn 1.有序的数组查找,使用二分法2.二分法查找第一次出现的位置,二分法查找最后一次出现的位置,end - start +1 left ...

  3. Hadoop系列-zookeeper基础

    目前是刚刚初学完zookeeper,这篇文章主要是简单的对一些基本的概念进行梳理强化. zookeeper基础概念的理解 有时候计算机领域很多名词都是从一长串英文提取首字母缩写而来,但很不幸zooke ...

  4. 在Visual Studio 2012中使用ASP.NET MVC5

    去年11月,.NET团队发布了用于 Visual Studio 2012 的 ASP.NET 和 Web 工具 2013.1 您可以从下面提供的链接下载该更新:  下载用于 Visual Studio ...

  5. 洛咕 P4131 [WC2005]友好的生物

    洛咕 P4131 [WC2005]友好的生物 首先可以发现\(C\)是没有用的,可以乘进所有的权值里面做 考虑没有最后一维的限制,那么两个生物的友好值就是 \(\sum_{i=1}^k|a_i-b_i ...

  6. DB异常状态:Recovery Pending,Suspect,估计Recovery的剩余时间

    一,RECOVERY PENDING状态 今天修改了SQL Server的Service Account的密码,然后重启SQL Server的Service,发现有db处于Recovery Pendi ...

  7. java对象是如何创建的

    虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符合引用代表的类是否已被加载.解析和初始化过.如果没有,那必须先执行相应的类加载过程. 在类加 ...

  8. 开发中常遇到的linux系统配置操作整理

    一直以来,工作中使用xshell连接linux虚拟机.常常需要在虚拟机中搭建一个新的Linux系统,为了满足操作需要,必不可少的是一系列配置.之前对这些指令都是记录在云笔记,但是零零散散,每次用时,都 ...

  9. bintray 在android3.2上传遇到的问题

    1.报错信息如下: Gradle DSL method not found: 'google()'Possible causes: The project 'JustTest' may be usin ...

  10. stl源码分析之hash table

    本文主要分析g++ stl中哈希表的实现方法.stl中,除了以红黑树为底层存储结构的map和set,还有用哈希表实现的hash_map和hash_set.map和set的查询时间是对数级的,而hash ...