5 条题解

  • 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;
    }
    
    • 1
      @ 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
        @ 2025-2-10 10:58:14
        
        

        #include<bits/stdc++.h> using namespace std; // typedef long long ll; const int N=21; int n; int d[N][N]; bool st[N]; int ans=0x3f3f3f3f; void dfs(int u,int cnt,int cost) { if(cost>ans) return; if(cntn&&un) { 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;; } } int main() { 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); cout<<ans; 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
            标签
            递交数
            206
            已通过
            42
            上传者