zoukankan      html  css  js  c++  java
  • 解题报告 Pizza

    2.pizza

    描述:

       Dsqwwe从小到大都没有吃过披萨,今天,他终于忍不住了,于是他叫了一份必胜客的外卖,由于不是dsqwwe一个人叫外卖,送外卖的小哥要到每个叫外卖的顾客家中然后最后回到必胜客…..这里有n-1个顾客叫外卖,必胜客在1号路口,叫外卖的顾客家分别在2,3,4…..n号路口,每两个路口都有一条通路,小哥想保证送外卖的时间最少,问最少时间为多少(一个路口可以多次经过的)

    输入:

      第一行:n(2<=n<=15)

      接下来n行每行n个数,第i行第j列代表从i到j的时间,当然这个矩阵是沿对角线对称的,且i行i列为0,除此外都不为0

    输出:

      最少时间

    样例输入:pizza

    4

    0 1 10 10

    1 0 1 2

    10 1 0 10

    10 2 10 0

    样例输出:

    8

     

     

     

    状态压缩 DP +记忆化搜索。

    首先用 f[i,j] 表示当走到了 状态,(二进制),最后一个走的是 时,最少的时间。

    然后,搜索。

    每次,枚举 j=1<<(n-1)-1 时,也就是全走完时的 ,然后倒着往前,依次枚举着,记忆化着搜,每一次如果枚举到第一个,且解比当前最优解好,就更新。

    然后就是这样。

     

    注意最后要走回到起点。

     

    program liukeke;

    var

      map:array[0..16,0..16] of longint;

      f:array[0..16,0..32770] of longint;

      n:longint;

      i,j,k,ans:longint;

    procedure init;

    var

      i,j:longint;

    begin

      fillchar(map,sizeof(map),127);

      readln(n);

      for i:=1 to n do

        for j:=1 to n do

      read(map[i,j]);

    end;

     

    procedure floyd;

    var

      i,j,k:longint;

    begin

      for k:=1 to n do

        for i:=1 to n do

      if i<>k then 

       for j:=1 to n do

         if (i<>j)and(j<>k) then 

       if map[i,j]>map[i,k]+map[k,j] then

         map[i,j]:=map[i,k]+map[k,j];

    end;

     

    function dfs(now,t:longint):longint;

    var

      i,temp:longint;

    begin

      if f[now,t]<maxlongint then exit(f[now,t]);

      if t=0 then 

      begin

        f[now,t]:=map[1,now+1];

    exit(f[now,t]);

      end;

      for i:=1 to n-1 do

      begin

        if (t and (1<<(i-1)) )=0 then continue;

    temp:=t-(1<<(i-1));

    if dfs(i,temp)+map[i+1,now+1]<f[now,t] then

      f[now,t]:=dfs(i,temp)+map[i+1,now+1];

      end;

      exit(f[now,t]);

    end;

     

    begin

      assign(input,'pizza.in');reset(input);

      assign(output,'pizza.out');rewrite(output);

      init;

      floyd;

      //dp;

      ans:=maxlongint;

      for i:=1 to n-1 do 

        for j:=0 to 1<<(n-1) do

      f[i,j]:=maxlongint; 

      for i:=1 to n-1 do

      begin

        k:=(1<<(n-1)-1)-(1<<(i-1));

    if dfs(i,k)+map[i+1,1]<ans then ans:=dfs(i,k)+map[i+1,1];

      end;

      writeln(ans);

      close(input);

      close(output);

    end.

     

     

  • 相关阅读:
    洛谷p1017 进制转换(2000noip提高组)
    Personal Training of RDC
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Eurasia
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Peterhof.
    Asia Hong Kong Regional Contest 2019
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Siberia
    XVIII Open Cup named after E.V. Pankratiev. Ukrainian Grand Prix.
    XVIII Open Cup named after E.V. Pankratiev. GP of SPb
    卜题仓库
    2014 ACM-ICPC Vietnam National First Round
  • 原文地址:https://www.cnblogs.com/SueMiller/p/2237231.html
Copyright © 2011-2022 走看看