4 条题解

  • 1
    @ 2025-1-7 0:37:04
    // https://dashoj.com/p/80
    #include <bits/stdc++.h>
    
    #define N 50
    using namespace std;
    typedef long long ll;
    int n, g[N][N], e; // 
    bool gb[N];
    ll ans = 0x3f3f3f3f;
    
    void dfs(int x, int a, ll an) {
    	if (a == e) {
    		ans = min(an + g[x][n], ans);
    		return;
    	}
    	for (int i = 2; i <= e; i++) {
    		if (i == x) continue;
    		if (!gb[i]) continue;
    		gb[i] = false;
    		if (an + g[x][i] < ans) dfs(i, a + 1, an + g[x][i]);
    		gb[i] = true;
    	}
    }
    
    int main() {
    	ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); //
    	fill(&gb[0], &gb[0] + N, true); //
    	cin >> n; //
    	e = n - 1; //
    	gb[1] = false;
    	for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) cin >> g[i][j]; //
    	dfs(1, 1, 0); //
    	cout << ans << endl; //
    	return 0;
    }
    
    • 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
          难度
          8
          标签
          递交数
          159
          已通过
          27
          上传者