• 解题报告 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.

     

     

  • 相关阅读:
    JavaScript Window
    3.1.3 背景音乐播放技术
    6.1 多媒体相关基本概念及计算问题
    11.5 知识产权考点讲解
    第15课 TortoiseGit程序操作介绍
    第16课 “远程 Git文档库” 的基础操作
    第11课 Git GUI程序的基本功能
    第12课 使用Git GUI
    第13课 SmartGit程序操作介绍
    第14课 SourceTree程序操作介绍
  • 原文地址:https://www.cnblogs.com/SueMiller/p/2237231.html
Copyright © 2020-2023  润新知