蓝桥杯-逗志芃的暴走

问题描述

  逗志芃是有妹子的现充,但是有时候妹子就是烦恼。因为逗志芃太逗了,所以这段时间妹子对逗志芃发动了技能无理取闹,妹子要去玩很多的景点。由于逗志芃之前抽机花费了太多的时间,不久以后又要微积分考试了,所以现在被妹子搞成暴走状态了。但是妹子永远是上帝,所以逗志芃只能带妹子出去玩,不过为了节约时间,他希望找到一条花费时间最少的一次性游览线路。

输入格式

  第一行1个数n,表示逗志芃所在的城市有多少个景点,接下来是一个n*n的矩阵。a(i,j)表示i号景点到j号景点的路上花费的时间是多少。

  接下来是一个数m,表示逗志芃妹子要去去的景点数目。由于妹子在无理取闹,所以可能会有重复的景点,不过只要去一次就可以了。接下来是m个数,就是妹子要去的景点编号。

输出格式

  一个数,最少的花费时间。

样例输入

3

0 1 2

1 0 3

2 3 0

3

2 3 1

样例输出

3

数据规模和约定

  0<n<=30,0<m<=20,时间<=1000000

初步思路:

没什么好说的,中二到爆的题目,题意比较清楚,先用Floyd算法求出各个点之间的最短距离,然后对目标点进行全排列,求出所有计划的距离,最后求最小值,求全排列当然离不开美妙的回溯啦:

n=int(input())
graph=[[] for i in range(n)]
for i in range(n):
    graph[i]=list(map(int,input().split()))
m=int(input())
nums=list(map(int,input().split()))
def folyd(graph):
    n=len(graph)
    for k in range(n):
        for i in range(n):
            for j in range(n):
                graph[i][j]=min(graph[i][j],graph[i][k]+graph[k][j])
folyd(graph)
class Solution:
    def __init__(self):
        self.path=[]
        self.min=1e9
    def solve(self,nums,graph):
        nums.sort()
        self.used=[False]*len(nums)
        self.backtracking(nums,graph)
        return self.min
    def backtracking(self,nums,graph):
        if len(self.path)==len(nums):
            res=0
            for i in range(len(self.path)-1):
                res+=graph[self.path[i]-1][self.path[i+1]-1]
            self.min=min(self.min,res)
        for i in range(len(nums)):
            if self.used[i]==True:
                continue
            if i>0 and nums[i]==nums[i-1] and self.used[i]==False:
                continue
            self.path.append(nums[i])
            self.used[i]=True
            self.backtracking(nums,graph)
            self.path.pop()
            self.used[i]=False
s=Solution()
print(s.solve(nums,graph))

结果0分,真晦气!!!

进阶思路:

再仔细读题,原来这女孩子没有公主命换了公主病,有重复的目标点,所以只能先对目标点集合进行去重,这里采用朴素的去重方法,先将列表转换为set集合,因为set集合不存在重复元素,最后在转换为列表形式,li=list(set(li)),然后回溯自然而然就没什么用了,不如直接内置函数itertool.permutations

from itertools import permutations
n=int(input())
graph=[[] for i in range(n)]
for i in range(n):
    graph[i]=list(map(int,input().split()))
m=int(input())
nums=list(map(int,input().split()))
nums=list(set(nums))
def folyd(graph):
    n=len(graph)
    for k in range(n):
        for i in range(n):
            for j in range(n):
                graph[i][j]=min(graph[i][j],graph[i][k]+graph[k][j])
folyd(graph)
result=[]
for temp in permutations(nums):
    res=0
    for i in range(len(temp)-1):
        res+=graph[temp[i]-1][temp[i+1]-1]
    result.append(res)
print(min(result))

完美AC

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值