[SPOJ PUTNIK]区间DP
知识点:dynamic programing
uncommon TSP
1. 题目链接
2. 题意描述
旅行商问题TSP( Travelling Salesman Problem)概都清楚,经典的NP难问题之一。这个题目是一个变式的TSP问题。
经典的TSP问题是指:城市与城市之间有边权,求经过所有城市有且仅有一次,最小边权之和。
这个题目增加了一个约束条件:对于标号为
K
的城市,所有标号小于
城市数目
2≤n≤1500
, 从
i
到
3. 解题思路
题目关键之所在,在于分析这个题目的特殊性。对于标号为
K
的城市,所有标号小于
然后,用
dp[u][i]=min{dp[u−1][i]+cost[u][u−1]}dp[i][u]=min{dp[i][u−1]+cost[u][u−1]}}i∈[1,u−1]dp[u][u−1]=min{dp[i][u−1]+cost[u][i]}dp[u−1][u]=min{dp[u−1][i]+cost[i][u]}}i∈[1,u−1]
4. 实现代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 1500 + 5;
const int INF = 0x3f3f3f3f;
int n, cost[MAXN][MAXN];
int dp[MAXN][MAXN];
int main() {
#ifdef ___LOCAL_WONZY___
freopen("input.txt", "r", stdin);
#endif // ___LOCAL_WONZY___
while(~scanf("%d", &n)) {
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= n; ++j) {
scanf("%d", &cost[i][j]);
dp[i][j] = INF;
}
}
dp[1][1] = dp[1][1] = 0;
dp[1][2] = dp[2][1] = cost[1][2];
for(int u = 3; u <= n; ++u) {
for(int i = 1; i < u - 1; i++) {
dp[u][u - 1] = min(dp[u][u - 1], dp[i][u - 1] + cost[u][i]);
dp[u - 1][u] = min(dp[u - 1][u], dp[u - 1][i] + cost[i][u]);
dp[u][i] = min(dp[u][i], dp[u - 1][i] + cost[u][u - 1]);
dp[i][u] = min(dp[i][u], dp[i][u - 1] + cost[u - 1][u]);
}
}
int ans = INF;
for(int i = 1; i < n; i++) {
ans = min(ans, dp[i][n]);
ans = min(ans, dp[n][i]);
}
printf("%d\n", ans);
}
return 0;
}