感觉网上很多题解写的似乎不清楚,这里说一下我的思路
显然对于每个用户的材料(设其比例为Ai,Bi,Ci),
我们要么最多用3种原料(设其比例为ai,bi,ci)混合成需要材料,要么一定混合不成,具体原因往下看
我们设这3种原料所取比例为x1,x2,x3,可得
x1*a1+x2*a2+x3*a3=Ai
x1*b1+x2*b2+x3*b3=Bi
x1*(1-a1-b1)+x2*(1-a2-b2)+x3*(1-a3-b3)=1-Ai-Bi
整理第三个式子可得x1+x2+x3=1 x3=1-x1-x2 (注意这里x1,x2,x3>=0)
带回到前两个式子可得
x1*a1+x2*a2+(1-x1-x2)*a3=Ai
x1*b1+x2*b2+(1-x1-x2)*b3=Bi
整理可得
x1*(a1-a3)+x2*(a2-a3)=Ai-a3
x1*(b1-b3)+x2*(b2-b3)=Bi-b3
看到这个式子大家仔细想就会发现,这其实就是:
向量(a1-a3,b1-b3)和(a2-a3,b2-b3)能否表示向量(Ai-a3,Bi-b3)
根据平面向量的理论我们知道上面的结论是正确的
学过向量的同学可能还会听过这样一个结论(很好证)
设OABC四点,B在线段AC上,O不与ABC共线
则向量OB=a向量OA+b向量OC 一定满足a+b=1 而这里我们的要求也是x1+x2<=1
也就是如果把ai,bi和A,B看做材料点(ai,bi)和原料点(Ai,Bi)
如果用户所需材料i能被原料融合,当且仅当存在三个原料点构成的三角形能把材料点围起来
于是下面的思路就很明显了,我们先求出原料点所组成的凸包,如果所有用户都在凸包内则有解否则无解
接下来我们要找的是最少凸包上的点组成的多边形就能把所有原料点包含了
首先我们要理解什么是包含,我们从凸包一点出发,沿着下凸线到上凸线的顺序走回起点
这样凸包上的每条边就是一个向量,包含的意思就是:每个原料点都必须在每个向量的左边(叉积判断)
于是这就好办了,于是我们穷举向量的起点i终点j,如果所有原料点都在这个向量的左边那么d[i,j]=1 否则d[i,j]=inf
下面我们只要求出一个最小环即可,这可以用floyd搞定
注意这里凸包上是不能存在三点共线的
比较恶心的是这道题要注意精度问题

 const eps=1e-10;
type point=record
x,y:double;
end; var a,b:array[..] of point;
w:array[..] of longint;
f:array[..,..] of longint;
ans,i,j,k,p,n,m:longint;
ch:boolean; function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end; procedure swap(var a,b:point);
var c:point;
begin
c:=a;
a:=b;
b:=c;
end; procedure sort(l,r:longint);
var i,j:longint;
p:point;
begin
i:=l;
j:=r;
p:=a[(l+r) shr ];
repeat
while (a[i].x<p.x) or (a[i].x=p.x) and (a[i].y<p.y) do inc(i);
while (p.x<a[j].x) or (a[j].x=p.x) and (p.y<a[j].y) do dec(j);
if not(i>j) then
begin
swap(a[i],a[j]);
inc(i);
dec(j);
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end; function cross(a,b,c:point):double;
begin
exit((b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y));
end; function check:boolean;
var i,j:longint;
begin
dec(k);
for i:= to k do
for j:= to n do
if cross(a[w[i]],a[w[i+]],b[j])<-eps then exit(false);
exit(true);
end; begin
readln(m,n);
for i:= to m do
readln(a[i].x,a[i].x,a[i].y);
for i:= to n do
readln(b[i].x,b[i].x,b[i].y);
if n= then
begin
writeln();
halt;
end;
for i:= to m do
begin
ch:=true;
for j:= to n do
if (a[i].x<>b[j].x) or (a[i].y<>b[j].y) then
begin
ch:=false;
break;
end;
if ch then //这里特判一下
begin
writeln();
halt;
end;
end;
sort(,m);
k:=;
w[]:=;
for i:= to m do
begin
while (k>) and (cross(a[w[k-]],a[w[k]],a[i])<eps) do dec(k);
inc(k); w[k]:=i;
end;
j:=k;
for i:=m- downto do
begin
while (k>j) and (cross(a[w[k-]],a[w[k]],a[i])<eps) do dec(k);
inc(k); w[k]:=i;
end;
if check then
begin
for i:= to k do
for j:= to k do
begin
f[i,j]:=m;
if i<>j then
begin
ch:=true;
for p:= to n do
if cross(a[w[i]],a[w[j]],b[p])<-eps then
begin
ch:=false;
break;
end;
if ch then f[i,j]:=;
end;
end; for p:= to k do
for i:= to k do
for j:= to k do
f[i,j]:=min(f[i,j],f[i,p]+f[p,j]);
ans:=m;
for i:= to k do
ans:=min(ans,f[i,i]);
writeln(ans);
end
else writeln(-);
end.

bzoj1027的更多相关文章

  1. 【bzoj1027】合金

    [bzoj1027]合金 分析 数形结合+计算几何+Floyd最小环. http://blog.csdn.net/popoqqq/article/details/40539273 虽然这样占大家的很不 ...

  2. bzoj1027【JSOI2007】合金

    题目描述 某公司加工一种由铁.铝.锡组成的合金.他们的工作很简单.首先进口一些铁铝锡合金原材料,不同种类的原材料中铁铝锡的比重不同.然后,将每种原材料取出一定量,经过融解.混合,得到新的合金.新的合金 ...

  3. bzoj1027 [JSOI2007]合金

    1027: [JSOI2007]合金 Time Limit: 4 Sec  Memory Limit: 162 MBSubmit: 2671  Solved: 703[Submit][Status][ ...

  4. bzoj1027 [HNOI2004]打鼹鼠

    [HNOI2004]打鼹鼠 2014年5月2日2,8605 Description 鼹鼠是一种很喜欢挖洞的动物,但每过一定的时间,它还是喜欢把头探出到地面上来透透气的.根据这个特点阿Q编写了一个打鼹鼠 ...

  5. bzoj1027 状压dp

    https://www.lydsy.com/JudgeOnline/problem.php?id=1072 题意 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除 试了一下发现暴力可过 ...

  6. bzoj千题计划123:bzoj1027: [JSOI2007]合金

    http://www.lydsy.com/JudgeOnline/problem.php?id=1027 因为x+y+z=1,所以z=1-x-y 第三维可以忽略 将x,y 看做 平面上的点 简化问题: ...

  7. BZOJ1027 [HNOI2004]打鼹鼠 【dp】

    1207: [HNOI2004]打鼹鼠 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 3647  Solved: 1746 [Submit][Sta ...

  8. BZOJ1027 [JSOI2007]合金 【计算几何 + floyd】

    题目 某公司加工一种由铁.铝.锡组成的合金.他们的工作很简单.首先进口一些铁铝锡合金原材料,不同种类的 原材料中铁铝锡的比重不同.然后,将每种原材料取出一定量,经过融解.混合,得到新的合金.新的合金的 ...

  9. bzoj题解汇总(1021~1031)

    bzoj1021:普通dp bzoj1022:裸的Anti-Nim 必胜:①sg=0且所有不超过1 ②sg>1且存在至少一个超过1 bzoj1023:http://www.cnblogs.com ...

随机推荐

  1. (转)QRCODE二维码介绍及常用控件推荐

    什么是QR Code码? QR Code码是由日本Denso公司于1994年9月研制的一种矩阵二维码符号,它具有一维条码及其它二维条码所具有的信息容量大.可靠性高.可表示汉字及图象多种文字信息.保密防 ...

  2. asp.net弹出框后页面走样

    1.去掉language='javascript' ,问题依旧 2.后面加上Response.Write("<script>document.location=document. ...

  3. HPDL380G8平台11.2.0.3 RAC实施手册

    HPDL380G8平台11.2.0.3 RAC实施手册   1 前言 此文档详细描述了Oracle 11gR2 数据库在HPDL380G上的安装RAC的检查及安装步骤.文档中#表示root用户执行,$ ...

  4. Huffman Coding 哈夫曼编码

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4096079.html 使用优先队列实现,需要注意以下几点: 1.在使用priority_qu ...

  5. C语言中的程序终止函数

    在C语言的标准库<stdlib.h>中提供了一些与正常或者不正常的程序终止有关的函数,下面分别对其进行简单介绍. 参考文献: [1] C和指针,P298,342 [2] C程序设计语言现代 ...

  6. Application.StartupPath同System.Environment.CurrentDirectory区别

    System.Windows.Forms.Application.StartupPath:获取启动了应用程序的可执行文件的路径,不包括可执行文件的名称. System.Environment.Curr ...

  7. MongoDB入门三步曲3--部署技术:主备、副本集和数据分片

    mongodb部署--主备.副本及数据分片 主备复制 副本集 数据分片 主备复制 主备复制是最基本的一种多点部署方案,在读写分离.热备份.数据恢复等方面具有重要作用. 在真实的生产环境,主备库肯定需要 ...

  8. 创建一个cocos2d-x工程添加一个自定义Scene并显示

    #include "cocos2d.h" class RunScene :public cocos2d::CCLayer { public: virtual bool init() ...

  9. PHP初学留神(二)

    1.===比较运算符 记得上上篇中说过===与==的问题.当时说,===还要类型相同.但到底是怎样呢?因为我们知道比较运算符是可以把两个值类型转换的.举个栗子,如果一个数字和字符串比较,则字符串会转化 ...

  10. mysql索引使用笔记

    1.使用explain语句查看性能mysql> explain select product_id from orders where order_id in (123, 312, 223, 1 ...