• tyvjP1288 飘飘乎居士取能量块


    P1288 飘飘乎居士取能量块
    时间: 1000ms / 空间: 131072KiB / Java类名: Main

    背景

    9月21日,pink生日;9月22日,lina生日;9月23日,轮到到飘飘乎居士(狂欢吧,(*^__^*) 嘻嘻……)。

    描述

      9月21日,今天是pink的生日,飘飘乎居士当然要去别人的领土大闹一番啦!
      为了收集更多的能量到pink家大闹,飘飘乎居士准备从后花园中取出自己多年积攒的p个能量块。后花园一共被划分n个地区,能量块被分散在里面,现在飘飘乎居士拿出地图,发现自己站在1的地方,而他要做的就是用最短的路程把所有的能量块取出,并且最后走到位于n的出口处,而飘飘乎居士一直是个懒人,他想知道最少要走多少路程才能够取到所有的能量块,并且走到出口

    输入格式

    第一行一个正整数n,表示花园被划分成了n个地区
    接下来一个n*n的矩阵,代表个点之间的相互距离,数据保证从i走到i没有路程
    在下来一个整数p,表示一共有p个能量块
    接下来一行,表示各个能量块的位置,数据保证1和n没有能量块,且每个地区最多一个能量块
    对于所有的数据 0<n<=100  0<=P<=10 任意两点的距离为一个小于1000的正整数

    输出格式

    一个数,飘飘乎居士所要行走的最小距离

    测试样例1

    输入

    3
    0 10 1
    3 0 5
    1 2 0
    1
    2

    输出

    7

    备注

    花园被分为3个地区,在2号地区有能量块,飘飘乎居士行走的路线如下
    1->3->2->1->3
    行走的总路程为7,也就是最后的答案。

    题解:

    裸状压。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <iostream>
     5 #include <algorithm>
     6 #define max(a, b) a > b ? a : b
     7 #define min(a, b) a < b ? a : b
     8 
     9 inline void read(int &x)
    10 {
    11     x = 0;char ch = getchar();char c = ch;
    12     while(ch > '9' || ch < '0')c = ch, ch = getchar();
    13     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
    14     if(c == '-')x = -x;
    15 }
    16 
    17 const int MAXN = 100 + 10;
    18 const int MAXP = 10 + 5;
    19 
    20 int g[MAXN][MAXN], n, p, dir[MAXP], ok1, ok2;
    21 int f[MAXN][1 << MAXP];
    22 
    23 int main()
    24 {
    25     memset(f, 0X3f, sizeof(f));
    26     read(n);
    27     for(register int i = 1;i <= n;++ i)
    28         for(register int j = 1;j <= n;++ j)
    29             read(g[i][j]);
    30     for(register int k = 1;k <= n;++ k)
    31         for(register int i = 1;i <= n;++ i)
    32             for(register int j = 1;j <= n;++ j)
    33                 g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
    34     read(p);
    35     for(register int i = 1;i <= p;++ i)
    36     {
    37         read(dir[i]);
    38         if(dir[i] == 1) ok1 = true;
    39         else if(dir[i] == n) ok2= true;
    40     }
    41     if(!ok1) dir[++ p] = 1;
    42     if(!ok2) dir[++ p] = n;
    43     
    44     std::sort(dir + 1, dir + 1 + p);
    45     f[1][1] = 0;
    46     //f[i][S]表示从1出发走到点i,取到了S的能量块的最短路径
    47     register int M = 1 << p, now, tmp;
    48     for(register int S = 1;S < M;++ S)
    49     {
    50         for(register int i = 1;i <= p;++ i)
    51         {
    52             if(!(S & (1 << (i - 1))))continue;
    53             now = dir[i];
    54             for(register int j = 1;j <= p;++ j)
    55             {
    56                 if(i == j)continue;
    57                 if(!(S & (1 << (j - 1))))continue;
    58                 tmp = dir[j];
    59                 f[now][S] = min(f[now][S], f[tmp][S ^ (1 << (i - 1))] + g[tmp][now]);
    60             }
    61         }
    62     }
    63     printf("%d", f[n][M - 1]);
    64     return 0;
    65 }
    tyvj1288
  • 相关阅读:
    python 按行读取判断是否为空
    python获取目录下所有文件
    Kolakoski
    最小背包问题
    python 求第k个最大数
    python 求最大子序列
    爬取数据的程序
    文件对比程序
    trsd_extract_EDSD_new
    tred_extract_EDED_new
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7269657.html
Copyright © 2020-2023  润新知