PUTNIK - Putnik
Chances are that you have probably already heard of the travelling salesman problem. If you have, then you are aware that it is an NP-hard problem because it lacks an efficient solution. Well, this task is an uncommon version of the famous problem! Its uncommonness derives from the fact that this version is, actually, solvable efficiently.
The travelling salesman is on a mission to visit N cities, each exactly once. The cities are represented by numbers 1, 2, …, N. What we know is the direct flight duration between each pair of cities. The salesman, being the efficient man that he is, wants to modify the city visiting sequence so that the total flight duration is the minimum possible.
Alas, all is not so simple. In addition, the salesman has a peculiar condition regarding the sequence. For each city labeled K must apply: either all cities with labels smaller than K have been visited before the city labeled K or they will all be visited after the city labeled K. In other words, the situation when one of such cities is visited before, and the other after is not allowed.
Assist the poor fellow in his ambitious mission and calculate the minimum total flight duration needed in order to travel to all the cities, starting from whichever and ending in whichever city, visiting every city exactly once, so that his peculiar request is fulfilled.
Input
The first line of input contains the positive integer N (2 ≤ N ≤ 1500), the number of cities. Each of the following N lines contains N positive integers from the interval [0, 1000]. The number in Bth place in the Ath row represents the flight duration between cities A and B; that number is equal to the Ath number in the Bth row. When A = B, that number is 0. Otherwise, it is a positive value.
Output
The first and only line of output must contain the required minimum total flight duration.
Example
Input:
3
0 5 2
5 0 4
2 4 0
Output:
7
Input:
4
4
0 15 7 8
15 0 16 9
7 16 0 12
8 9 12 0
Output:
31
Clarification of the first example:
the optimal sequence is 2, 1, 3 or 3, 1, 2. The sequence 1, 3, 2 is even more favorable, but it does not fulfill the salesman’s condition.
Clarification of the second example:
the sequence is either 3, 1, 2, 4 or 4, 2, 1, 3.
题意:一个推销员要经过编号为1-n的城市,每两个城市之间有个边权,对于一个任意的编号为K的城市,所有标号小于K的要么在游览K之前被游览完,要么先游览完K之后才能游览,求走完所有城市的最小权值和。每个城市只能走一遍且起点终点任意。
解题思路:对于一个K而言,要么他是在编号比他小的所有数前面,要么就是在比他小的所有数后面,因此我们不难想到枚举,每次将最大的数放在最前面或者最后面,但是因为有n的数,所以时间复杂度就至少是O(2^n),因此我们会考虑用dp优化。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define maxn 1555
using namespace std;
int n,a[maxn][maxn],dp[maxn][maxn],ans=99999999;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) scanf("%d",&a[i][j]);
for(int i=1;i<=n+1;i++)
for(int j=1;j<=n+1;j++) dp[i][j]=99999999;
dp[n+1][n+1]=0;
for(int i=n;i>=1;i--){
for(int j=i+1;j<=n+1;j++){
dp[i][i+1]=min(dp[i][i+1],dp[i+1][j]+a[j][i]);
dp[i][j]=min(dp[i][j],dp[i+1][j]+a[i+1][i]);
}
}
for(int i=2;i<=n;i++){
ans=min(ans,dp[1][i]+a[1][i]);
}
printf("%d\n",ans);
return 0;
}