codeforces 8C - Looking for Order 状态DP

来源:互联网 发布:玻璃切割排版算法 编辑:程序博客网 时间:2024/06/04 19:49


一个女孩整理箱子,箱子的位置不可以改变,她一次可以拿两个或者是一个行李,女孩移动时间花费是她移动距离的平方。



int  dist[maxn][maxn] ;int  dp[1<<maxn]  , father[1<<maxn] ;pair<int , int> pt[maxn]  , p ;int  gtd(int i , int j){     return   (pt[i].first - pt[j].first) * (pt[i].first - pt[j].first)            + (pt[i].second - pt[j].second) * (pt[i].second - pt[j].second) ;}int  main(){     int  n  ,  x , y ;     while(cin>>p.first>>p.second){          scanf("%d" , &n) ;          for(int i = 0 ; i < n ; i++)  scanf("%d%d" , &pt[i].first , &pt[i].second) ;          pt[n] = p ;          for(int i = 0 ; i <= n ; i++)             for(int j = i+1 ; j <= n ; j++) dist[i][j] = dist[j][i] = gtd(i , j) ;          memset(dp , -1 , sizeof(dp)) ;          dp[0] = 0  ;          for(int i = 0 ; i < (1<<n) ; i++){               if(dp[i] == -1) continue ;               for(int j = 0 ; j < n ; j++){                   if((i & (1<<j)) == 0){                         int t = i ^ (1<<j) ;                         int dis = dp[i] + 2 * dist[j][n] ;                         if(dp[t] == -1 || dp[t] > dis){                              dp[t] = dis ;                              father[t] = i ;                         }                         for(int k = 0 ; k < n ; k++){                              if((t & (1<<k)) == 0){                                   int t2 = t ^ (1<<k) ;                                   int dis = dp[i] + dist[j][n] + dist[j][k] + dist[k][n] ;                                   if(dp[t2] == -1 || dp[t2] > dis){                                        dp[t2] = dis ;                                        father[t2] = i ;                                   }                              }                         }                         break ;                   }               }          }          cout<< dp[(1<<n) - 1]<<endl ;          int u = (1<<n) - 1 ;          vector<int> ans ; ans.clear() ;          while(u){               int f = father[u] ;               int c = f ^ u ;               ans.push_back(0) ;               vector<int> v ; v.clear() ;               for(int i = 0 ; i < n ; i++){                    if(c & (1 << i)) v.push_back(i+1) ;               }               for(int i = v.size()-1 ; i >= 0 ; i--) ans.push_back(v[i]) ;               u = f ;          }          ans.push_back(0)  ;          printf("%d" , ans[ans.size() - 1]) ;          for(int i = ans.size() - 2 ; i >= 0 ; i--) printf(" %d" , ans[i]) ;          puts("") ;     }     return 0 ;}


0 0
原创粉丝点击