题目链接 洛谷P1850
2016NOIP Day1 T2 T3难度互换真的坑死人啊..........
floyd+DP 就是写起来有点眼花的危险.....
可以先跑个最短路把两两教室间的最短距离先预处理出来
blue_tree大佬(field)说:v才300你不用floyd难道跑Dijkstra???
注意一下重边就好
然后就是概率DP
f[i][k][j]表示第i个时间段的申请状况为k,前i个共用了j次申请机会的最优值
其中 k==1 表示第i个时间段进行了申请 k==0 表示第i个时间段未进行申请
要注意对于申请了的情况要考虑成功和不成功两种的概率
对于i未申请的情况
(1)i-1也没申请
f[i][0][j]=min(f[i][0][j],f[i-1][0][j]+map[c[i-1][0]][c[i][0]]);
(2)i-1申请了
f[i][0][j]=min(f[i][0][j],f[i-1][1][j]+(1-k[i-1])*map[c[i-1][0]][c[i][0]]+k[i-1]*map[c[i-1][1]][c[i][0]]);
同理对于i申请的情况
f[i][1][j]=min(f[i-1][0][j-1]+(1-k[i])*map[c[i-1][0]][c[i][0]]+k[i]*map[c[i-1][0]][c[i][1]],f[i-1][1][j-1]+k[i-1]*k[i]*map[c[i-1][1]][c[i][1]]+(1-k[i-1])*k[i]*map[c[i-1][0]][c[i][1]]+k[i-1]*(1-k[i])*map[c[i-1][1]][c[i][0]]+(1-k[i-1])*(1-k[i])*map[c[i-1][0]][c[i][0]]);
(写完眼睛疼....)
模拟考的时候手抖打错一个字符 样例居然没错...一下掉回40分...
还有提交迟了一分钟系列....也是悲催.....
换个教室真麻烦....
{Beginner_df016}
var i,j,n,m,x,y,s,v,e:longint;
map:array[0..307,0..307]of longint;
c:array[0..2007,0..2]of longint;
k:array[0..2007]of double;
f:array[0..2007,0..1,0..2007]of double;
t,ans:double;
function minint(a,b:longint):longint;
begin
if a<b then exit(a); exit(b);
end;
function min(a,b:double):double;
begin
if a<b then exit(a); exit(b);
end;
procedure floyd;
var i,j,k:longint;
begin
for k:=1 to v do
for i:=1 to v do
for j:=1 to v do
map[i,j]:=minint(map[i,j],map[i,k]+map[k,j]);
end;
begin
readln(n,m,v,e);
for i:=0 to v do
for j:=0 to v do
map[i,j]:=maxlongint div 3;
for i:=1 to n do read(c[i][0]);
for i:=1 to n do read(c[i][1]);
for i:=1 to n do read(k[i]);
for i:=1 to e do
begin
readln(x,y,s);
if s<map[x,y] then
begin map[x,y]:=s; map[y,x]:=s; end;
end;
for i:=1 to v do map[i][i]:=0;
floyd;
fillchar(f,sizeof(f),$7f);
f[1][0][0]:=0; f[1][1][1]:=0;
for i:=2 to n do
begin
f[i][0][0]:=f[i-1][0][0]+map[c[i-1][0]][c[i][0]];
for j:=1 to minint(m,i) do
begin
f[i][0][j]:=min(f[i-1][0][j]+map[c[i-1][0]][c[i][0]],
f[i-1][1][j]+(1-k[i-1])*map[c[i-1][0]][c[i][0]]+k[i-1]*map[c[i-1][1]][c[i][0]]);
f[i][1][j]:=f[i-1][0][j-1]+(1-k[i])*map[c[i-1][0]][c[i][0]]+k[i]*map[c[i-1][0]][c[i][1]];
t:=f[i-1][1][j-1];
t:=t+k[i-1]*k[i]*map[c[i-1][1]][c[i][1]];
t:=t+(1-k[i-1])*k[i]*map[c[i-1][0]][c[i][1]];
t:=t+k[i-1]*(1-k[i])*map[c[i-1][1]][c[i][0]];
t:=t+(1-k[i-1])*(1-k[i])*map[c[i-1][0]][c[i][0]];
f[i][1][j]:=min(f[i][1][j],t);
end;
end;
ans:=f[n][0][0];
for i:=1 to m do
begin
ans:=min(ans,f[n][0][i]);
ans:=min(ans,f[n][1][i]);
end;
writeln(ans:0:2);
end.