Judges' response

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 741    Accepted Submission(s): 429

Problem Description
  The contest is running and the judges is busy watching the progress of the contest. Suddenly, N - 1 (N <= 16) contestants hand up their hand at the same time. The judges should go to answer the contestants' question one by one. The judges already foresee that answering contest i's question would cost Ci minutes. In order to serve all the contestant, each judges is assigned to serve some subset of the contestants. As the judges have limited patience, each one of them can serve the contestants for no more than M minutes.
  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.
 
Input
  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)
 
Output
  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.
 
Sample Input
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

 
Sample Output
1 6 2 8 -1 -1 8 467

题意:

  第一问:n-1个人有问题需要裁判答复、每个人需要Ci的时间、每个裁判最多回答M时间的问题、问最小需要几个裁判。

  第二问:每个人有个位置、所有裁判都在一个位置、问所有裁判回答完问题并回到原点加起来走过的距离最小是多少。

  第一问和第二问是独立的,不一定在最少裁判的基础上来走。

解题:

  第一问就是一个带有状态的01背包。

  第二问是多旅行商问题(MTSP)。

AC代码:

/** @xigua */
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<cstring>
#include<deque>
#include<queue>
#include<set>
#include<string>
#include<map>
#include<climits>
#define inf LLONG_MAX
#define INF 9e7+5
#define PI acos(-1)
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = 1e2 + 5;
const ll mod = 3e12 + 7;
const db eps = 1e-9;
int n, m, x[maxn], y[maxn], c[maxn];
int dis[maxn][maxn], dp[1<<16];
int sta[1<<16], len, best[1<<16], en[16][1<<16]; //en的第二维代表状态,比如en[j][i]代表在i状态下以j结尾的最小距离
bool xx[1<<16]; int get_dis(int x1, int x2, int y1, int y2) {
return ceil(sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)));
} void init() {
memset(xx, 0, sizeof(xx));
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) dis[i][j] = get_dis(x[i], x[j], y[i], y[j]);
for (int i = 0; i < (1<<n); i++) {
best[i] = INF;
dp[i] = INF;
for (int j = 0; j < n; j++)
en[j][i] = INF;
}
en[0][1] = best[0] = len = dp[0] = 0;
} bool ok(int x) {//判断当前状态能否由一个裁判回答完
int sum = 0;
for (int i = 0; i < n; i++) {
if (x&(1<<i))
sum += c[i];
}
return m >= sum;
} void get_sta() {
for (int i = 0; i < (1<<n); i++) {
if (ok(i))
sta[++len] = i, xx[i] = 1;
}
} int solve_bag() {
for (int i = 1; i <= len; i++) {
for (int j = (1<<n) - 1; j >= 0; j--) {
if (!(sta[i] & j)) {
dp[sta[i]|j] = min(dp[sta[i]|j], dp[j] + 1);
}
}
}
return dp[(1<<n)-1] == INF ? -1 : dp[(1<<n)-1];
} int solve_dd() {
for (int i = 0; i < (1<<n); i++) {
if (xx[i]) {
for (int j = 0; j < n; j++) {
if (i&(1<<j)) {
best[i] = min(best[i], en[j][i] + dis[j][0]);
for (int k = 0; k < n; k++) {
if (!(i&(1<<k))) {
en[k][i|(1<<k)] = min(en[k][i|(1<<k)], en[j][i] + dis[j][k]);
}
}
}
}
}
}
for (int i = 1; i < (1<<n); i++)
if (i&1)
for (int j = i&(i-1); j; j = i&(j-1)) //枚举比当前低的每个状态
best[i] = min(best[i], best[(i-j)|1] + best[j|1]);
return best[(1<<n)-1];
} void solve() {
while (cin >> n >> m) {
for (int i = 0; i < n; i++) cin >> x[i] >> y[i];
for (int i = 0; i < n; i++) cin >> c[i];
init();
get_sta();
int ans1= solve_bag();
if (ans1 == -1) cout << "-1 -1\n";
else cout << ans1 << ' ' << solve_dd() << endl;
}
} int main() {
//cin.sync_with_stdio(false);
//freopen("tt.txt", "r", stdin);
//freopen("hh.txt", "w", stdout);
int t = 1;
//cin >> t;
while (t--) {
solve();
} return 0;
}

  

HDU 4281 (状态压缩+背包+MTSP)的更多相关文章

  1. HDU 4739 Zhuge Liang's Mines (状态压缩+背包DP)

    题意 给定平面直角坐标系内的N(N <= 20)个点,每四个点构成一个正方形可以消去,问最多可以消去几个点. 思路 比赛的时候暴力dfs+O(n^4)枚举写过了--无意间看到有题解用状压DP(这 ...

  2. HDU 1074 (状态压缩DP)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目大意:有N个作业(N<=15),每个作业需耗时,有一个截止期限.超期多少天就要扣多少 ...

  3. hdu 4739(状态压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4739 思路:状态压缩. #include<iostream> #include<cs ...

  4. HDU 3341 状态压缩DP+AC自动机

    题目大意: 调整基因的顺序,希望使得最后得到的基因包含有最多的匹配串基因,使得所能达到的智商最高 这里很明显要用状态压缩当前AC自动机上点使用了基因的情况所能达到的最优状态 我最开始对于状态的保存是, ...

  5. hdu 2167(状态压缩基础题)

    题意:给你一个矩阵,让你在矩阵中找一些元素使它们加起来和最大,但是当你使用某一个元素时,那么这个元素周围的其它八个元素都不能取! 分析:这是一道比较基础的状态压缩题,也是我做的第三道状态压缩的题,但是 ...

  6. hdu 1565(状态压缩基础题)

    题意:容易理解. 分析:这是我做的状态压缩第二题,一开始超内存了,因为数组开大了,后来超时了,因为能够成立的状态就那么多,所以你应该先把它抽出来!!总的来说还是比较简单的!! 代码实现: #inclu ...

  7. HDU 2553 状态压缩

    N皇后问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  8. hdu 3006(状态压缩)

    The Number of set Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  9. hdu 2489(状态压缩+最小生成树)

    Minimal Ratio Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

随机推荐

  1. macbook pro上安装虚拟机

    第一步:下载MacHunter的app应用商店 第二步:在MacHunter内下载Parallels Desktop虚拟机 第三步:如果在这个商店下载不下来,在网络资源上直接下载Parallels D ...

  2. Watir: 如何处理简单的网页弹出警告框?

    以下是一个很经典的把Watir与AutoIt连接在一起的实例.如果我们对AutoIT了解的更多,处理类似的问题会更加简单.以下实例会判断页面上是否有某“删除”链接,一旦有该链接,就点击,然后点击弹出的 ...

  3. bzoj1089严格n元树——DP+高精度

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1089 f[d]为深度小于等于d的树的个数: 从根节点出发,有n个子树,乘法原理可以得到 f[ ...

  4. 微信小程序服务类目大坑:特殊行业服务类目所需资质材料

    作为一个技术开发人员,遇到特殊行业服务类目所需资质材料,只能叫苦连天了,妈的,这个不是技术可以解决的问题,如果技术可以解决的问题都不是问题. 百牛信息技术bainiu.ltd整理发布于博客园 特殊行业 ...

  5. vue 基本知识整理

    1 每个Vue.js应用都是通过构造函数Vue创建一个Vue的根实例 2 可以扩展Vue构造器,从而使用预定义选项创建可复用的组件构造器 所有的Vue.js组件其实都是被扩展的Vue实例 每一个VUE ...

  6. XTU1267:Highway(LCA+树的直径)

    传送门 题意 有n个小镇,Bobo想要建造n-1条边,并且如果在u到v建边,那么花费是u到v的最短路长度(原图),问你最大的花费. 分析 比赛的时候没做出来,QAQ 我们首先要找到树的直径起点和终点, ...

  7. 退出ACM?

    我不知道为什么我有这样的想法,纵观CCCC,太弱太弱,再不把自己埋起来,狠起来,就真的非常菜了,去刷难题吧!我不管老郭的数据,只管自己的实力,每天三道难题CF的C题+总结.以及刷水题!!!(刷CF的B ...

  8. bzoj 2440: [中山市选2011]完全平方数【莫比乌斯函数+二分】

    二分答案,然后用莫比乌斯函数作为容斥系数,计算当前枚举的mid内有几个满足要求的数 #include<iostream> #include<cstdio> #include&l ...

  9. PAT团体程序设计天梯赛 - 模拟赛

    由于本人愚笨,最后一题实在无力AC,于是只有前14题的题解Orz 总的来说,这次模拟赛的题目不算难,前14题基本上一眼就有思路,但是某些题写起来确实不太容易,编码复杂度有点高~ L1-1 N个数求和 ...

  10. Luogu P1417烹调方案【dp/背包】By cellur925

    题目传送门 我们看到这道题,就会想起背包.于是我就一顿01背包敲,结果发现只有30分.后来看题解发现需要对输入的食材进行排序. 我们回想国王游戏一题,各位大臣的排列顺序会对权值造成影响,所以我们就预先 ...