您的位置:首页 > 其它

GDKOI2016Day1第二题 不稳定的传送门 解题报告

2016-02-26 19:27 411 查看

GDKOI2016Day1第二题T2题解

题目描述略

样例解释:

首先,数组Fi表示由i至n的最优期望方案的值。

先将i连向i+1的那条边看成一条费用为W,成功传送的概率为P,P=1(100%),门的终点为U,U=i+1

当我们做到第i个点时,我们可以通过已做完的点j的Fj的值转移过来。

假设做到了第i个点,考虑门的使用顺序,对门的顺序进行一次全排列,选最优方案,便是Fi的值。

用样例来举例子。

i=4时,Fi=0

i=3时,只能选择一扇门,故Fi=W1+P1*FU1=30

(U1=4,P1=1,W1=30)

i=2时,可以选择两扇门,第一扇是(U1=3,P1=1,W1=30)、

第二扇是(U2=3,P2=0.9,W2=10)

对这两扇门的顺序进行全排列,发现先放第二扇门更优。

具体如下:

对应内容第二扇门第一扇门
使用此门传送的概率11-P2=0.1
门费用W2=10W1=30
传送的终点U2=3U1=3
总期待费用VV2=W2+P2*FU2=37V1=(1-P2)(W1+P1*FU1)=6
Fi=F2=V2+V1=36+6=43

i=1时,一样有两扇门可以选,第一扇是(U1=4,P1=0.5,W1=30)、

第二扇是(U2=2,P2=1,W2=30)

对这两扇门的顺序进行全排列,发现先放第一扇门更优。

具体如下:

对应内容第一扇门第二扇门
使用此门传送的概率11-P1=0.5
门费用W1=30W2=30
传送的终点U1=4U2=2
总期待费用VV1=W1+P1*FU1=30V2=(1-P1)(W2+P2*FU2)=36.5
Fi=F1=V1+V2=30+36.5=66.5

所以,答案就是66.5

30分算法

每个点有最多不超过5扇门,枚举门的使用顺序,选最优答案即可。

100分算法

可以枚举门的使用顺序,那么能不能通过某种方式求出最优的使用顺序呢?

不妨先将一种门(共k扇门)的使用顺序的期望值列出来。

Fi=W1+P1FU1+(1-P1)(W2+P2FU2+(1-P2)(W3+P3FU3+(1-P3)(……)))

设 1-Pi=Vi,Wi+PiFUi=Ki

则Fi=W1+V1(W2+V2(W3+V3(…)))

将这个式子拆括号

则Fi=W1+V1W2+V1V2W3+V1V2V3W4…+V1V2~Vk−2Vk−1Wk

假设已经放了前q扇门,且为最优解,接下来考虑该放哪扇门才是最优的。假设现在有两扇门i,j可选择,如果先放第i扇门更优则一定满足

W1+V1W2+V1V2W3+V1V2V3W4…+V1V2~VqWi+V1V2~VqViWj

<W1+V1W2+V1V2W3+V1V2V3W4…+V1V2~VqWj+V1V2~VqVjWi

化简得

Wi+ViWj<Wj+VjWi

Wi-VjWi<Wj-ViWj

(1-Vj)Wi<(1-Vi)Wj

(1−Vj)Wj<(1−Vj)Wj

即PjWj+VjWj<PiWi+ViWi

PiWi+ViWi>PjWj+VjWj

此时,含i和j的项全部移到了一边,也就是说上述不等式成立时,先放i比先放j更优,且如果i比j优,j比l优,则i比l优,具有了传递性

现在只需按照 PiWi+ViWi从大到小排序,便可以得到最优的门的使用顺序了.

Code(Pascal)

var
f,bl,px:array[0..1000000] of extended;
door:array[0..1000000,1..3] of longint;
en:array[0..1000000] of longint;
n,m,j,k,l,i,o,p:longint;
dqbl:extended;
procedure qsort(l,r:longint);
var
i,j,m:longint;
begin
i:=l;
j:=r;
m:=door[(l+r) div 2,1];
repeat
while door[i,1]<m do inc(i);
while door[j,1]>m do dec(J);
IF i<=j then
begin
door[0]:=door[i];
door[i]:=door[j];
door[j]:=door[0];
bl[0]:=bl[i];
bl[i]:=bl[j];
bl[j]:=bl[0];
inc(i);
dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end;
procedure kp(l,r:longint);
var
i,j:longint;
m:extended;
begin
i:=l;
j:=r;
m:=px[(l+r) div 2]/bl[(l+r) div 2];
repeat
while px[i]/bl[i]<m do inc(i);
while px[j]/bl[j]>m do dec(j);
if i<=j then
begin
px[0]:=px[i];
px[i]:=px[j];
px[j]:=px[0];
bl[0]:=bl[i];
bl[i]:=bl[j];
bl[j]:=bl[0];
door[0]:=door[i];
door[i]:=door[j];
door[j]:=door[0];
inc(i);
dec(j);
end;
until i>j;
if l<j then kp(l,j);
if i<r then kp(i,r);
end;
begin
assign(input,'portal.in'); reset(input);
assign(output,'portal.out'); rewrite(output);
readln(n,m);
for i:=1 to n-1 do
begin
read(p);
door[i,1]:=i;
door[i,2]:=i+1;
door[i,3]:=p;
bl[i]:=1;
inc(en[i]);
end;
for i:=1 to m do
begin
readln(door[i+n-1,1],door[i+n-1,2],bl[i+n-1],door[i+n-1,3]);
inc(en[door[i+n-1,1]]);
end;
qsort(1,n+m-1);
for i:=2 to n do
en[i]:=EN[I-1]+EN[I];
en[0]:=0;
f
:=0;
for i:=n-1 downto 1 do
begin
for l:=en[i-1]+1 to en[i] do
px[l]:=(door[l,3]+bl[l]*f[door[l,2]]);
kp(en[i-1]+1,en[i]);
f[i]:=0;
for l:=en[i] downto en[i-1]+1 do
f[i]:=f[i]*(1-bl[l])+px[l];
end;
writeln(f[1]:0:2);
close(input);
close(output);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: