用
f[i][j]
表示到第
i
节课交了
每个状态由上一天转移过来,上一天有申请或不申请两种情况,根据两天申请与否可以算出从上一天到这一天的期望步数,在上一天申请和不申请两种决策中取最优。
具体转移见代码。
var
f,g:array[0..2001,0..2001] of extended;
dis:array[0..301,0..301] of longint;
c,d:array[0..2001] of longint;
k:array[0..2001] of extended;
n,m,v,e,i,j,l,a,b,w:longint;
ans:extended;
function lmin(a,b:longint):longint;
begin if (a<b) then exit(a) else exit(b); end;
function min(a,b:extended):extended;
begin if (a<b) then exit(a) else exit(b); end;
begin
read(n,m,v,e);
for i:=1 to n do read(c[i]);
for i:=1 to n do read(d[i]);
for i:=1 to n do read(k[i]);
for i:=1 to v do
for j:=1 to v do
dis[i][j]:=maxlongint>>1;
for i:=1 to v do
dis[i][i]:=0;
for i:=1 to e do
begin
read(a,b,w);
dis[a][b]:=lmin(dis[a][b],w);
dis[b][a]:=lmin(dis[b][a],w);
end;
for l:=1 to v do
for i:=1 to v do
for j:=1 to v do
dis[i][j]:=lmin(dis[i][j],dis[i][l]+dis[l][j]);
for i:=0 to n do
for j:=0 to m do
begin
f[i][j]:=1e9;
g[i][j]:=1e9;
end;
f[1][0]:=0;
g[1][1]:=0;
for i:=2 to n do
for j:=0 to m do
begin
f[i][j]:=f[i-1][j]+dis[c[i-1]][c[i]];
if (j=0) then continue;
f[i][j]:=min(f[i][j],g[i-1][j]+k[i-1]*dis[d[i-1]][c[i]]
+(1-k[i-1])*dis[c[i-1]][c[i]]);
g[i][j]:=min(f[i-1][j-1]+k[i]*dis[c[i-1]][d[i]]+(1-k[i])*dis[c[i-1]][c[i]],
g[i-1][j-1]+k[i-1]*k[i]*dis[d[i-1]][d[i]]
+k[i-1]*(1-k[i])*dis[d[i-1]][c[i]]
+(1-k[i-1])*k[i]*dis[c[i-1]][d[i]]
+(1-k[i-1])*(1-k[i])*dis[c[i-1]][c[i]]);
end;
ans:=1e9;
for j:=0 to m do ans:=min(ans,f[n][j]);
for j:=0 to m do ans:=min(ans,g[n][j]);
writeln(ans:0:2);
end.