3 条题解

  • 0
    @ 2024-4-12 19:10:19

    开O2优化可以用dfsAC

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    
    const int N = 21;
    
    int n;
    int d[N][N];
    bool st[N];
    LL ans = 0x3f3f3f3f;
    
    void dfs(int u, int cnt, LL cost)// 当前所在岛屿, 总共经过了多少个岛屿, 经过cnt个岛屿的花费
    {
    	if(cost > ans) return;
    	if (cnt == n && u == n)
    	{
    		ans = min(ans, cost);
    		return;
    	}
    
    	for (int i = 1; i <= n; i++)
    	{
    		if (i == u) continue;
    		if (st[i]) continue;
    		if (d[u][i] >= ans) continue;
    
    		st[i] = true;
    		dfs(i, cnt + 1, cost + d[u][i]);
    		st[i] = false;
    
    	}
    }
    
    void solve()
    {
    	cin >> n;
    	for (int i = 1; i <= n; i++)
    		for (int j = 1; j <= n; j++)
    			cin >> d[i][j];
    			
    	st[1] = true;
    	dfs(1, 1, 0);
    }
    
    int main()
    {
    	solve();
    	cout << ans << endl;
    	return 0;
    }
    
    • 0
      @ 2024-4-9 17:31:44
      #include<bits/stdc++.h>
      using namespace std;
      int n;int mp[20][20];
      bool vis[20];
      using ll=long long;
      ll ans=1e9+5;
      
      void dfs(int x,ll ann){//x是到了哪座岛出发,ann是花费
          if(x==n){
              for(int i=1;i<n;i++){
                  if(!vis[i])return;
              }
              ans=min(ans,ann);
              return;
          }
          if(ann>ans){
              return;
          }
          for(int j=1;j<=n;j++){
              if(x==j) continue;
              if(vis[j]) continue;
              vis[j]=true;
              dfs(j,ann+mp[x][j]);
              vis[j]=false;
          }
      
      }
      int main(){
          cin>>n;
          for(int i=1;i<=n;i++){
              for(int j=1;j<=n;j++){
                  cin>>mp[i][j];
              }
          }
          vis[1]=true;
          dfs(1,0);
          cout<<ans<<endl;
          return 0;
      }
      
      • 0
        @ 2024-4-9 10:51:29

        使用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;
        }
        
        • 1

        信息

        ID
        80
        时间
        1000ms
        内存
        256MiB
        难度
        7
        标签
        递交数
        124
        已通过
        24
        上传者