[nhzxoi2017]noip2016tg1

来源:互联网 发布:哪个火车票比较好知乎 编辑:程序博客网 时间:2024/06/08 19:53

提高组

D1

1.      玩具谜题

模拟,但不知道为什么,考试时数组少写了一个0,导致只有80分。以后一定要仔细检查数组的范围!

var n,m,i,q,w,tt:longint;

ch:char;

a:array[0..100005] of longint;

st:array[0..100005] of string;

begin

 readln(n,m);

  fori:=1 to n do readln(a[i],ch,st[i]); tt:=1;

  fori:=1 to m do

 begin

    readln(q,w);

   if ((q=0) and (a[tt]=0)) or ((q=1) and (a[tt]=1))then

   while w<>0 do

   begin

     dec(tt);

     dec(w);

     if tt=0 then tt:=n;

   end;

   if ((q=1) and (a[tt]=0)) or ((q=0) and (a[tt]=1)) then

   while w<>0 do

   begin

      inc(tt);

     dec(w);

     if tt=n+1 then tt:=1;

   end;

 end;

 writeln(st[tt]);

end.

3.换教室

题目的意思是:有N节课,每一节课都有两个课室Ci和Di在上。给你M个换课室的机会(不需全部用完),同时每一节课换教室都有一个被通过的概率,问如何换教室使得从课室到课室的总消耗体力值最小。

首先我们会用最短路径处理所有教室之间的道路。因为教室数<=300,故用floyd算法。

然后我们发现每一个课室都有换和不换两种类型。并可以想到背包的模型。由数学期望的线性我们就知道这一个点可以根据上一个选不选来计算期望。

所以f[i,j,不选](i为课室,已经换了j个课室)= min(f[i-1,j,0]+a[c[i-1],c[i]],f[i-1,j,1]+k[i-1]*a[d[i-1],c[i]]+(1-k[i-1])*a[c[i-1],c[i]])

f[i,j,选]=min(f[i-1,j-1,1]+a[d[i-1],d[i]]*k[i]*k[i-1]+a[d[i-1],c[i]]*k[i-1]*(1-k[i])+a[c[i-1],d[i]]*(1-k[i-1])*k[i]+a[c[i-1],c[i]]*(1-k[i-1])*(1-k[i]),f[i-1,j-1,0]+a[c[i-1],d[i]]*k[i]+a[c[i-1],c[i]]*(1-k[i]))

有几个注意点:1.每个点有多条路径,所以一开始赋值是a[i,j]=min(w,a[i,j]);

2.      有自己到自己的路径,所以最后要for i:=1 to v do a[i,i]:=0;

var dp:array [-1..2003,-1..2003,0..1] ofreal;

   a:array[-1..2003,-1..2003] of longint;

   c,d:array[0..2003] of longint;

   k:array[0..2003] of real;

   n,m,v,e,i,kk,j,o,p,w:longint;

    minn,temp:real;

function min(a,b:real):real;

begin

  ifa<b then exit(a) else exit(b);

end;

function min1(a,b:longint):longint;

begin

  ifa<b then exit(a) else exit(b);

end;

begin

 readln(n,m,v,e);

  fori:=1 to n do read(c[i]); readln;

  fori:=1 to n do read(d[i]); readln;

  fori:=1 to n do read(k[i]); readln;

  fori:=-1 to 2000 do for j:=-1 to 2000 do a[i,j]:=999999999;

  fori:=1 to e do begin read(o,p,w); a[o,p]:=min1(a[o,p],w); a[p,o]:=a[o,p]; end;readln;

  fori:=1 to v do a[i,i]:=0;

  forkk:=1 to v do

   for i:=1 to v do

     for j:=1 to v do a[i,j]:=min1(a[i,j],a[i,kk]+a[kk,j]);

  fori:=1 to n do for j:=0 to m do begin dp[i,j,0]:=99999999; dp[i,j,1]:=99999999;end;

 dp[1,0,0]:=0; dp[1,1,1]:=0;

  fori:=2 to n do

   for j:=0 to m do

   begin

 dp[i,j,0]:=min(dp[i-1,j,0]+a[c[i-1],c[i]],dp[i-1,j,1]+k[i-1]*a[d[i-1],c[i]]+(1-k[i-1])*a[c[i-1],c[i]]);

     if j>0 then begindp[i,j,1]:=dp[i-1,j-1,0]+a[c[i-1],d[i]]*k[i]+a[c[i-1],c[i]]*(1-k[i]);

temp:=dp[i-1,j-1,1]+a[d[i-1],d[i]]*k[i]*k[i-1]+a[d[i-1],c[i]]*k[i-1]*(1-k[i])+a[c[i-1],d[i]]*(1-k[i-1])*k[i]+a[c[i-1],c[i]]*(1-k[i-1])*(1-k[i]);

     dp[i,j,1]:=min(dp[i,j,1],temp); end;

   end;

    minn:=maxlongint;

  fori:=0 to m do minn:=min(minn,min(dp[n,i,0],dp[n,i,1]));

 writeln(minn:0:2);

end.

 

0 0
原创粉丝点击