返回题解分享
讨论 / 题解分享/ 帖子详情

海贼王之伟大航路 - 题解

使用dfs + 剪枝,最多可过70%数据

#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 阅读
回复 (0)
默认 最新
暂无回复,快来抢沙发!