毕业旅行问题
题目描述
小明目前在做一份毕业旅行的规划。
打算从北京出发,分别去若干个城市,然后再回到北京,每个城市之间均乘坐高铁,且每个城市只去一次。
由于经费有限,希望能够通过合理的路线安排尽可能的省一些路上的花销。
给定一组城市和每对城市之间的火车票的价钱,找到每个城市只访问一次并返回起点的最小车费花销。
- 输入描述
城市个数n(1<n≤20,包括北京)
城市间的车票价钱:n行n列的矩阵m[n][n]
- 输出描述
最小车费花销s
- 示例
# 输入
4
0 2 6 5
2 0 4 4
6 4 0 2
5 4 2 0
# 输出
13
暴力求解
由于城市间来往的路径是一样的,这里利用集合来避免一半的消耗。即使这样,内存仍然超限。
from itertools import permutations
def minimum_cost(n, seq):
possible = list(permutations(range(1, n), n-1))
end = set()
for pu in possible:
if pu not in end and pu[::-1] not in end:
end.add(pu)
spend = float('inf')
for eu in end:
current = [0] + list(eu) + [0]
value = 0
for ci in range(len(current)-1):
pre, cur = current[ci], current[ci+1]
value += seq[pre][cur]
if spend > value:
spend = value
return spend
if __name__ == '__main__':
n = int(input().strip())
seq = []
for _ in range(n):
seq.append(list(map(int, input().strip().split())))
res = minimum_cost(n, seq)
print(res)
旅行商问题
状态转移:当前在城市start,经过的城市为mid时,可以转移到城市vu。Python语言实现超时,该用C++语言。
def minimum_cost(n, seq):
value = 1 << (n-1)
dp = [[float('inf')]*value for _ in range(n)]
for nu in range(n):
dp[nu][0] = seq[nu][0]
for vu in range(1, value):
for start in range(n):
if dp[start][vu] == float('inf'):
for mid in range(1, n):
if (vu>>(mid-1)) & 1 == 1:
current = seq[start][mid] + dp[mid][vu^(1<<(mid-1))]
if current < dp[start][vu]:
dp[start][vu] = current
return dp[0][-1]
if __name__ == '__main__':
n = int(input().strip())
seq = []
for _ in range(n):
seq.append(list(map(int, input().strip().split())))
res = minimum_cost(n, seq)
print(res)
# 样例学习
4
0 2 6 5
2 0 4 4
6 4 0 2
5 4 2 0
Update: 0 1 0
1 0 3
[0, 4, inf, inf, inf, inf, inf, inf]
[2, inf, inf, inf, inf, inf, inf, inf]
[6, inf, inf, inf, inf, inf, inf, inf]
[5, inf, inf, inf, inf, inf, inf, inf]
Update: 1 1 0
1 1 3
[0, 4, inf, inf, inf, inf, inf, inf]
[2, 2, inf, inf, inf, inf, inf, inf]
[6, inf, inf, inf, inf, inf, inf, inf]
[5, inf, inf, inf, inf, inf, inf, inf]
Update: 2 1 0
1 2 3
[0, 4, inf, inf, inf, inf, inf, inf]
[2, 2, inf, inf, inf, inf, inf, inf]
[6, 6, inf, inf, inf, inf, inf, inf]
[5, inf, inf, inf, inf, inf, inf, inf]
Update: 3 1 0
1 3 3
[0, 4, inf, inf, inf, inf, inf, inf]
[2, 2, inf, inf, inf, inf, inf, inf]
[6, 6, inf, inf, inf, inf, inf, inf]
[5, 6, inf, inf, inf, inf, inf, inf]
Update: 0 2 0
2 0 3
[0, 4, 12, inf, inf, inf, inf, inf]
[2, 2, inf, inf, inf, inf, inf, inf]
[6, 6, inf, inf, inf, inf, inf, inf]
[5, 6, inf, inf, inf, inf, inf, inf]
Update: 1 2 0
2 1 3
[0, 4, 12, inf, inf, inf, inf, inf]
[2, 2, 10, inf, inf, inf, inf, inf]
[6, 6, inf, inf, inf, inf, inf, inf]
[5, 6, inf, inf, inf, inf, inf, inf]
Update: 2 2 0
2 2 3
[0, 4, 12, inf, inf, inf, inf, inf]
[2, 2, 10, inf, inf, inf, inf, inf]
[6, 6, 6, inf, inf, inf, inf, inf]
[5, 6, inf, inf, inf, inf, inf, inf]
Update: 3 2 0
2 3 3
[0, 4, 12, inf, inf, inf, inf, inf]
[2, 2, 10, inf, inf, inf, inf, inf]
[6, 6, 6, inf, inf, inf, inf, inf]
[5, 6, 8, inf, inf, inf, inf, inf]
Update: 0 1 2
Update: 0 2 1
3 0 3
[0, 4, 12, 12, inf, inf, inf, inf]
[2, 2, 10, inf, inf, inf, inf, inf]
[6, 6, 6, inf, inf, inf, inf, inf]
[5, 6, 8, inf, inf, inf, inf, inf]
Update: 1 1 2
Update: 1 2 1
3 1 3
[0, 4, 12, 12, inf, inf, inf, inf]
[2, 2, 10, 10, inf, inf, inf, inf]
[6, 6, 6, inf, inf, inf, inf, inf]
[5, 6, 8, inf, inf, inf, inf, inf]
Update: 2 1 2
Update: 2 2 1
3 2 3
[0, 4, 12, 12, inf, inf, inf, inf]
[2, 2, 10, 10, inf, inf, inf, inf]
[6, 6, 6, 6, inf, inf, inf, inf]
[5, 6, 8, inf, inf, inf, inf, inf]
Update: 3 1 2
Update: 3 2 1
3 3 3
[0, 4, 12, 12, inf, inf, inf, inf]
[2, 2, 10, 10, inf, inf, inf, inf]
[6, 6, 6, 6, inf, inf, inf, inf]
[5, 6, 8, 8, inf, inf, inf, inf]
Update: 0 3 0
4 0 3
[0, 4, 12, 12, 10, inf, inf, inf]
[2, 2, 10, 10, inf, inf, inf, inf]
[6, 6, 6, 6, inf, inf, inf, inf]
[5, 6, 8, 8, inf, inf, inf, inf]
Update: 1 3 0
4 1 3
[0, 4, 12, 12, 10, inf, inf, inf]
[2, 2, 10, 10, 9, inf, inf, inf]
[6, 6, 6, 6, inf, inf, inf, inf]
[5, 6, 8, 8, inf, inf, inf, inf]
Update: 2 3 0
4 2 3
[0, 4, 12, 12, 10, inf, inf, inf]
[2, 2, 10, 10, 9, inf, inf, inf]
[6, 6, 6, 6, 7, inf, inf, inf]
[5, 6, 8, 8, inf, inf, inf, inf]
Update: 3 3 0
4 3 3
[0, 4, 12, 12, 10, inf, inf, inf]
[2, 2, 10, 10, 9, inf, inf, inf]
[6, 6, 6, 6, 7, inf, inf, inf]
[5, 6, 8, 8, 5, inf, inf, inf]
Update: 0 1 4
Update: 0 3 1
5 0 3
[0, 4, 12, 12, 10, 11, inf, inf]
[2, 2, 10, 10, 9, inf, inf, inf]
[6, 6, 6, 6, 7, inf, inf, inf]
[5, 6, 8, 8, 5, inf, inf, inf]
Update: 1 1 4
Update: 1 3 1
5 1 3
[0, 4, 12, 12, 10, 11, inf, inf]
[2, 2, 10, 10, 9, 9, inf, inf]
[6, 6, 6, 6, 7, inf, inf, inf]
[5, 6, 8, 8, 5, inf, inf, inf]
Update: 2 1 4
Update: 2 3 1
5 2 3
[0, 4, 12, 12, 10, 11, inf, inf]
[2, 2, 10, 10, 9, 9, inf, inf]
[6, 6, 6, 6, 7, 8, inf, inf]
[5, 6, 8, 8, 5, inf, inf, inf]
Update: 3 1 4
Update: 3 3 1
5 3 3
[0, 4, 12, 12, 10, 11, inf, inf]
[2, 2, 10, 10, 9, 9, inf, inf]
[6, 6, 6, 6, 7, 8, inf, inf]
[5, 6, 8, 8, 5, 6, inf, inf]
Update: 0 2 4
Update: 0 3 2
6 0 3
[0, 4, 12, 12, 10, 11, 13, inf]
[2, 2, 10, 10, 9, 9, inf, inf]
[6, 6, 6, 6, 7, 8, inf, inf]
[5, 6, 8, 8, 5, 6, inf, inf]
Update: 1 2 4
Update: 1 3 2
6 1 3
[0, 4, 12, 12, 10, 11, 13, inf]
[2, 2, 10, 10, 9, 9, 11, inf]
[6, 6, 6, 6, 7, 8, inf, inf]
[5, 6, 8, 8, 5, 6, inf, inf]
Update: 2 2 4
Update: 2 3 2
6 2 3
[0, 4, 12, 12, 10, 11, 13, inf]
[2, 2, 10, 10, 9, 9, 11, inf]
[6, 6, 6, 6, 7, 8, 7, inf]
[5, 6, 8, 8, 5, 6, inf, inf]
Update: 3 2 4
Update: 3 3 2
6 3 3
[0, 4, 12, 12, 10, 11, 13, inf]
[2, 2, 10, 10, 9, 9, 11, inf]
[6, 6, 6, 6, 7, 8, 7, inf]
[5, 6, 8, 8, 5, 6, 8, inf]
Update: 0 1 6
Update: 0 2 5
Update: 0 3 3
7 0 3
[0, 4, 12, 12, 10, 11, 13, 13]
[2, 2, 10, 10, 9, 9, 11, inf]
[6, 6, 6, 6, 7, 8, 7, inf]
[5, 6, 8, 8, 5, 6, 8, inf]
Update: 1 1 6
Update: 1 2 5
Update: 1 3 3
7 1 3
[0, 4, 12, 12, 10, 11, 13, 13]
[2, 2, 10, 10, 9, 9, 11, 11]
[6, 6, 6, 6, 7, 8, 7, inf]
[5, 6, 8, 8, 5, 6, 8, inf]
Update: 2 1 6
Update: 2 2 5
Update: 2 3 3
7 2 3
[0, 4, 12, 12, 10, 11, 13, 13]
[2, 2, 10, 10, 9, 9, 11, 11]
[6, 6, 6, 6, 7, 8, 7, 8]
[5, 6, 8, 8, 5, 6, 8, inf]
Update: 3 1 6
Update: 3 2 5
Update: 3 3 3
7 3 3
[0, 4, 12, 12, 10, 11, 13, 13]
[2, 2, 10, 10, 9, 9, 11, 11]
[6, 6, 6, 6, 7, 8, 7, 8]
[5, 6, 8, 8, 5, 6, 8, 8]
13
#include <iostream>
#include <vector>
using namespace std;
int mininum_cost(int n, vector<vector<int>> seq)
{
int value = 1 << (n-1);
int inf = 0x7fffffff;
vector<vector<int>> dp(n, vector<int>(value, inf));
for(int nu=0; nu<n; nu++)
dp[nu][0] = seq[nu][0];
for(int vu=1; vu < value; vu++)
{
for(int start=0; start<n; start++)
{
if(dp[start][vu] == inf)
{
for(int mid=1; mid<n; mid++)
{
if(((vu>>(mid-1)) & 1) == 1)
{
int current = seq[start][mid] + dp[mid][(vu^(1<<(mid-1)))];
if(current < dp[start][vu])
dp[start][vu] = current;
}
}
}
}
}
return dp[0][value-1];
}
int main()
{
int n;
cin >> n;
vector<vector<int>> seq(n, vector<int>(n, 0));
for(int ni=0; ni<n; ni++)
for(int nj=0; nj<n; nj++)
cin >> seq[ni][nj];
int res = mininum_cost(n, seq);
cout << res << endl;
return 0;
}
(最近更新:2019年09月07日)