感觉网上很多题解写的似乎不清楚,这里说一下我的思路
显然对于每个用户的材料(设其比例为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. redis 实践—— sorted set, hash set

    在这里就不谈redis的安装与启动啦,网上太多人写这个了. 从最近的一个项目[钻石夺宝]说起,如果大家有玩过一元夺宝或者全名夺宝的话,大概会知道如果参与人数多的话,每隔几秒.快的话每隔一秒都会新生成一 ...

  2. 11_Jaxws常用注解

    [不使用注解] 默认namespace是服务类包名的倒序 默认portType是服务类的类名 ............... 注解的所起的作用: Jaxws提供的注解可以对WebService的接口规 ...

  3. 在Linux系统下安装大于mysql5.5版本的数据库

    linux下mysql 5.5的安装方法: 1.安装所需要系统库相关库文件      gcc等开发包,在安装linux系统的时候安装. 2.创建mysql安装目录 # mkdir -p /usr/lo ...

  4. 事件兼容IE

    addEvent:function(target, functionref, tasktype) { if (target.addEventListener) target.addEventListe ...

  5. Centos 添加SWAP(交换分区)

    一般情况下,内存过小时,可以增加 swap,大小为内存的2倍为宜,具体设置如下: 1.进入目录cd /var/ 2.获取要增加的SWAP文件块(这里以1GB为例)dd if=/dev/zero of= ...

  6. 使用weinre通过PC浏览器调试手机网页

    Weinre是什么? Weinre代表Web Inspector Remote,是一种远程调试工具.举个例子,在电脑上可以即时的更改手机上对应网页的页面元素.样式表, 或是查看Javascript变量 ...

  7. Redhat 6.5 x64 下载地址

    http://ftp.okhysing.is/ftp/redhat/6.5/isos/x86_64/

  8. python使用mysqldb连接数据库操作方法示例详解

    这篇文章主要介绍了python mysqldb使用方法,大家参考使用 复制代码代码如下: # -*- coding: utf-8 -*- #mysqldb  # site www.jbxue.com ...

  9. Linux主机在LNMP环境中同时运行多个PHP版本

    这次遇到的问题是,客户网站已经使用PHP5.4运行多个网站程序,但是新安装的程序需要使用PHP5.3. 从我之前的经验来看,给网站更换PHP版本,可能会带来意想不到的后果.比如,之前某客户Discuz ...

  10. Pascal、VB、C#、Java四种语法对照表

    因为工作原因,自学会了vb后陆续接触了其它语言,在工作中经常需要与各家使用不同语言公司的开发人员做程序对接,初期特别需要一个各种语法的对照比,翻看了网络上已有高人做了整理,自己在他基础上也整理了一下, ...