使用dfs + 剪枝,最多可过70%数据
正解DP
#include <bits/stdc++.h>
using namespace std;
const int N = 20;
const int INF = 1e9;
int mp[N][N];
int vis[N];
int n;
int mn = INF;
int mem[N][N][N];
int dfs(int x, int sum, int cnt) {
if (cnt == n && x == n) {
mn = min(mn, sum);
return mn;
}
if (cnt == n || sum >= mn) {
return INF;
}
for (int i = 1; i <= n; ++i) {
if (!vis[i]) {
vis[i] = 1;
return dfs(i, sum + mp[x][i], cnt + 1);
vis[i] = 0;
}
}
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
scanf("%d", &mp[i][j]);
}
}
vis[1] = 1;
printf("%d\n", dfs(1,0,1));
return 0;
}正解DP
#include <bits/stdc++.h>
using namespace std;
const int N = 20;
const int INF = 1e9;
int mp[N][N];
int dp[1 << N][N];
int n;
int main() {
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
scanf("%d", &mp[i][j]);
}
}
for (int i = 0; i < (1 << n); ++i) {
for (int j = 0; j < n; ++j) {
dp[i][j] = INF;
}
}
dp[1][0] = 0;
for (int i = 1; i < (1 << n); ++i) {
for (int j = 0; j < n; ++j) {
if ((i >> j) & 1) {
for (int k = 0; k < n; ++k) {
if ((i >> k) & 1 && j != k) {
dp[i][j] = min(dp[i][j], dp[i ^ (1 << j)][k] + mp[k][j]);
}
}
}
}
}
printf("%d\n", dp[(1 << n) - 1][n - 1]);
return 0;
}
0 回复
0 转发
0 喜欢
1 阅读



