[gym101982M][思维好题][凸壳]Mobilization

题目链接

20182019-acmicpc-pacific-northwest-regional-contest-div-1-en.pdf

题目大意

现在有\(n\)种士兵,每种士兵有一个血量\(h_i\)和潜力\(p_i\)以及花销\(c_i\)。

你一共有\(C\)块钱,现在你要用这些钱去雇佣士兵,你雇佣某种士兵的数量可以是任意实数(也就是说并不一定要整数)。最后你构建出来军团的战斗力等于总血量与总潜力的乘积。

\((n\le3\times 10^4, 1\le C\le 10^5,1\le c_i \le 10^5, 0.0\le h_i,p_i\le 1.0)\)

做法分析

为了简化问题,我们将每个人看作一个向量\(\mathbf{v}\)。

\[\mathbf{v}_i = C
\begin{bmatrix}
\frac{h_i}{c_i} \\
\\
\frac{p_i}{c_i} \\
\end{bmatrix}
\]

这样构造是因为可以将组建军团的过程简化成一个向量集合的线性组合。

我们可以将最后组合出来的向量视作一个新的向量\(\mathbf{u}\),其两维的乘积即为答案。

\[\mathbf{u} = \sum_{i=1}^n x_i\mathbf{v}_i \\
需要满足\sum_{i=1}^n x_i \le 1 \\
求 \max\{\mathbf{u}_0 \times \mathbf{u}_1\}
\]

可以发现这样的形式正好描述了一个平面上一个点集(将每个向量\(v_i\)的终点看作一个点,起点为原点),构成凸包,内部的点的贡献被覆盖。

我们的答案一定在凸壳上且最偏右上角的边界上,因为\(f(x,y) = xy , x\ge0,y\ge0\)(相当于两维相乘的值)的最值总是在凸型区域的右上角取到(马鞍形)。以下是无聊做的图...

由于答案总在右上角的边界上,我们只要维护上凸壳即可,,问题解决,复杂度\(O(N\log N)\)

PS:代码是纯c,就是想尝试一下新东西,绘制了几个图片,好理解一点,这篇题解就是纯消磨时间的..。

/*
gym101982m, 数学,优化,函数最值
*/
#include <stdio.h>
#include <stdlib.h>
#define max(a, b) (a) > (b) ? (a) : (b);
#define min(a, b) (a) < (b) ? (a) : (b);
#define N 30005
#define eps 1e-7
typedef long long LL;
struct point {
double x, y;
};
inline struct point sub(struct point a, struct point b) {
return (struct point){.x = a.x - b.x, .y = a.y - b.y};
}
inline double cross(struct point a, struct point b) {
return a.x * b.y - a.y * b.x;
}
inline int sgn(double x) { return (x > eps) - (x < eps); }
int cmp(const void* a, const void* b) {
struct point* p = (struct point*)a;
struct point* q = (struct point*)b;
if (!sgn(p->x - q->x)) {
return sgn(p->y - q->y);
} else
return sgn(p->x - q->x);
}
double calc(struct point u, struct point v) {
double A = (u.x - v.x) * (u.y - v.y);
double B = (u.x - v.x) * v.y + (u.y - v.y) * v.x;
double C = v.x * v.y;
double x = -0.5 * B / A;
if (sgn(x - 0.0) <= 0)
return 0;
else
x = min(x, 1.0);
return (A * x + B) * x + C;
}
int main() {
struct point v[N], ch[N];
double c[N], h[N], p[N], ans = 0.0;
int n, C, m = 0; scanf("%d%d", &n, &C);
for (int i = 0; i < n; i++) {
scanf("%lf%lf%lf", &c[i], &h[i], &p[i]);
v[i] = (struct point){.x = h[i] / c[i] * C, .y = p[i] / c[i] * C};
ans = max(ans, v[i].x * v[i].y);
}
qsort(v, n, sizeof(v[0]), cmp);
/* for (int i = 0; i < n; i++) {
printf("point %.3f %.3f\n", v[i].x, v[i].y);
}*/
for (int i = 0; i < n; i++) {
while (m > 1 &&
sgn(cross(sub(ch[m - 1], ch[m - 2]), sub(v[i], ch[m - 2]))) > 0)
m--;
ch[m++] = v[i];
}
/* for (int i = 0; i < m; i++) {
printf("convex hull %.3f %.3f\n", ch[i].x, ch[i].y);
}*/
for (int i = 0; i < m - 1; i++) {
ans = max(ans, calc(ch[i], ch[i + 1]));
}
printf("%.2f\n", ans);
return 0;
}
/*
4 100000
300 1 0.02
500 0.2 1
250 0.3 0.1
1000 1 0.1
*/

[Gym101982M][思维好题][凸壳]Mobilization的更多相关文章

  1. ZOJ 3937 More Health Points (2016 浙江省赛 B题,可持久维护凸壳)

    题目链接  2016 ZJCPC Problem B 题意  CF 660F的树上版本. 其他做的方法都差不多,关键是把凸壳放到树上. 每次确定扔掉几个元素的时候直接$O(1)$修改(先不清楚这个位置 ...

  2. [BZOJ2726][SDOI2012]任务安排(DP+凸壳二分)

    2726: [SDOI2012]任务安排 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1580  Solved: 466[Submit][Statu ...

  3. XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Khamovniki Problem J Stairways解题报告(分块+维护凸壳)

    首先ORZ一发Claris聚聚的题解:http://www.cnblogs.com/clrs97/p/8689215.html,不然我可能没机会补过这道神题了. 这里写一个更详细的题解吧(我还是太菜了 ...

  4. bzoj2402 陶陶的难题II 分数规划+树剖+线段树维护凸壳+二分

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2402 题解 看上去很像分数规划的模型.于是就二分吧.令 \[ \begin{align*}\f ...

  5. 【JZOJ3299】【SDOI2013】保护出题人 三分+凸壳

    题面 ​出题人铭铭认为给SDOI2012 出题太可怕了,因为总要被骂,于是他又给SDOI2013 出题了. 参加SDOI2012 的小朋友们释放出大量的僵尸,企图攻击铭铭的家.而你作为SDOI2013 ...

  6. YbtOJ#853-平面标记【整体二分,凸壳】

    正题 题目链接:http://www.ybtoj.com.cn/contest/119/problem/3 题目大意 给出\(n\)个点\((x_i,y_i)\),\(m\)次给出\((k_i,a_i ...

  7. BZOJ 3672 [Noi2014]购票 (熟练剖分+凸壳维护)

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3672 题意:给出一棵有根树(1为根),边有长度.每个点u有三个属性(len[u], ...

  8. bzoj 3165: [Heoi2013]Segment 动态凸壳

    3165: [Heoi2013]Segment Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 202  Solved: 89[Submit][Stat ...

  9. [CF1137E]Train Car Selection[维护凸壳]

    题意 题目链接 分析 首先,如果加到了车头所有之前的车厢都不可能成为答案. 如果加到了车尾,容易发现对于 \(x_2<x_3\) 而言在某个时刻会出现 2 又比 3 优的情况. 具体来讲,如果存 ...

随机推荐

  1. bzoj3887: [Usaco2015 Jan]Grass Cownoisseur

    题意: 给一个有向图,然后选一条路径起点终点都为1的路径出来,有一次机会可以沿某条边逆方向走,问最多有多少个点可以被经过?(一个点在路径中无论出现多少正整数次对答案的贡献均为1) =>有向图我们 ...

  2. 【51nod1743】雪之国度(最小生成树+倍增)

    点此看题面 大致题意: 给你一张无向连通图,其中每条边的边权为这条边连接的两点的权值之差.每次询问两点之间是否存在两条不重复的路径,若存在则输出这两条路径上最大值的最小值. 大致思路 这题显然就是要让 ...

  3. Processing入门指南

    简介 Processing 是由 MIT 媒体实验室的 Casey Reas 和 Benjamin Fry 发明的一种开源可视化编程语言.Processing为数字媒体与娱乐交互设计而创建,其目的是通 ...

  4. OO2019第四单元作业总结

    一.本单元两次作业的架构设计  1.第一次作业 第一次作业由于时间仓促,没有过多的架构设计,就直接补全了所给的MyUmlInteraction类,导致整个程序的代码风格和效率都不高,在强测中也因此失掉 ...

  5. 第29题:LeetCode54:Spiral Matrix螺旋矩阵

    给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素. 示例 1: 输入: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ...

  6. js原生实现三级联动下拉菜单

    js代码: <!doctype html> <html> <head> <meta charset="utf-8"> <tit ...

  7. java 获取request中的请求参数

    1.get 和 post请求方式 (1)request.getParameterNames(); 获取所有参数key后.遍历request.getParameter(key)获取value (2)re ...

  8. Java 替换word文档文字,指定位置插入图片

    先说下 需要的依赖包 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ex ...

  9. Mysql--数据定义语言(DDL)

    DDL(Data Definition languages)数据定义语言,这些语句主要定义了不同的数据段,数据表.列.索引等操作,主要关键字有create.drop.alter. 一. 数据库的操作 ...

  10. 认识mysql(3)

    认识mysql第三篇,发出的内容适合初学者,如果能持续关注我的博客,可以全面的掌握mysql的常用知识,后续我也会陆续发出python相关的知识,关注我,和我一共进步吧! 1.SQL查询 1.执行顺序 ...