现在的位置: 首页 > 综合 > 正文

poj1946

2018年01月15日 ⁄ 综合 ⁄ 共 1397字 ⁄ 字号 评论关闭

【题意】

n(n<=20)头牛进行自行车比赛

需要跑d(d<=100)圈

每头牛初始有e(e<=100)的体力

流程按整分钟划分

比赛的时候若以x圈每分钟的速度前进,则领头牛每分钟消耗x*x的体力,其余牛每分钟消耗x的体力

若牛的体力小于x,则牛掉队

可在每分钟调换领头牛

只要有一头牛跑完要求圈数则算完成,问最快跑完需要几分钟

【输入】

 一行n,e,d

【输出】

若能跑完则输出最小用时,否则输出0

最初的思路是用【以跑圈数】【领头牛体力】【剩余牛体力】【剩余牛数量】来表示状态

但是这个是四维的,应该会超,数组也开不下

之后发现实际上领头牛是一头用完掉队了再让剩余牛上,不会出现归队的情况

这样剩余牛的状态都是一样的,剩余牛以x圈每分钟的速度前进,则每分钟消耗x的体力,

反过来说跑y圈,剩余牛门则消耗y的体力

所以剩余牛的体力可以用e-【以跑圈数】算出,省下了一维

dp,用f[i][j][k]表示已经跑了i圈,领头牛有j的体力,除领头牛外剩余牛有k只所需的最小时间

初始状态为f[0][e][n-1]

然后用类似spfa的方式拓展状态求解

program poj1946;
var
  n,e,d,i,j,k,tot,ans:longint;
  f:array [0..101,0..101,0..21] of longint;
  dl:array [0..100001] of record
                           d,e,n:longint;
                         end;
begin
  read(n,e,d);
  fillchar(f,sizeof(f),63);
  if (e<d)or(n=0) then
    begin
      writeln(0);
      exit;
    end;
  f[0,e,n-1]:=0;
  tot:=1;
  dl[1].d:=0;
  dl[1].e:=e;
  dl[1].n:=n-1;
  ans:=maxlongint;
  i:=1;
  while i<=tot do
    begin
      if dl[i].d=d then
        if f[dl[i].d,dl[i].e,dl[i].n]<ans then
          ans:=f[dl[i].d,dl[i].e,dl[i].n];
      for j:=1 to trunc(e-dl[i].d) do
        begin
          if j*j<=dl[i].e then
            if f[dl[i].d+j,dl[i].e-j*j,dl[i].n]>f[dl[i].d,dl[i].e,dl[i].n]+1 then
              begin
                f[dl[i].d+j,dl[i].e-j*j,dl[i].n]:=f[dl[i].d,dl[i].e,dl[i].n]+1;
                inc(tot);
                dl[tot].d:=dl[i].d+j;
                dl[tot].e:=dl[i].e-j*j;
                dl[tot].n:=dl[i].n;
              end;
          if (dl[i].n>0)and(e-dl[i].d>=j*j) then
            if f[dl[i].d+j,e-dl[i].d-j*j,dl[i].n-1]>f[dl[i].d,dl[i].e,dl[i].n]+1 then
              begin
                f[dl[i].d+j,e-dl[i].d-j*j,dl[i].n-1]:=f[dl[i].d,dl[i].e,dl[i].n]+1;
                inc(tot);
                dl[tot].d:=dl[i].d+j;
                dl[tot].e:=e-dl[i].d-j*j;
                dl[tot].n:=dl[i].n-1;
              end;
        end;
      inc(i);
    end;
  writeln(ans);
end.
【上篇】
【下篇】

抱歉!评论已关闭.