C++系列 HDU1619

case1  :  

1 2 3 4 4 5

16

case2 :

1 2 1 5 4 5

11

N* M的地图, 从左往右走,只能走同行或者相邻行, 1行与N行相邻。求最小的权值和 ,并输出字典序最小的路径。

1 、 vector 的逆序操作写法

2 、对于 vector< vector<int>  >  排序方式就是字典序从小到大的方式。

2、 整体的设计


const  int  Max_N = 12 ;
const  int  Max_M = 108 ;
const  int  inf = (1<<30) + (1<<29);

int   x[Max_N][Max_M] ;
int   dp[Max_N][Max_M] ;
int   father[Max_N][Max_M] ;
int   N , M ;

pair<int , int>  Gao(int i , int j){
      vector< pair<int ,int> > List ;
      List.clear() ;
      if(i == 1)
          List.push_back(make_pair(dp[N][j-1] , N)) ;
      else
          List.push_back(make_pair(dp[i-1][j-1] , i-1))  ;

      if(i == N)
          List.push_back(make_pair(dp[1][j-1] , 1)) ;
      else
          List.push_back(make_pair(dp[i+1][j-1] , i+1))  ;

      List.push_back(make_pair(dp[i][j-1] , i)) ;
      sort(List.begin() , List.end()) ;
      return List[0] ;
}

vector< vector<int> > List ;

int   main(){
      int i , j  , ans , u ;
      pair<int , int> now ;
      while(cin>>N>>M){
            for(i = 1 ; i <= N ; i++)
                for(j = 1 ; j <= M ; j++)
                    scanf("%d" ,&x[i][j]) ;
            memset(dp , 0 , sizeof(dp)) ;
            memset(father, -1 , sizeof(father)) ;
            for(i = 1 ; i <= N ; i++)
                dp[i][1] = x[i][1] ;
            for(j = 2 ; j <= M ; j++){
                for(i = 1 ; i <= N ; i++){
                     now = Gao(i , j) ;
                     dp[i][j] += now.first + x[i][j];
                     father[i][j] = now.second ;
                }
            }
            ans = inf ;
            for(i = 1 ; i <= N ; i++)
                ans = min(ans , dp[i][M]) ;
            vector<int> nowLis ;
            List.clear() ;
            for(i = 1 ; i <= N ; i++){
                 if(ans == dp[i][M]){
                      u = i ;
                      nowLis.clear() ;
                      for(j = M ; j >= 1 ; j--){
                            nowLis.push_back(u) ;
                            u = father[u][j] ;
                      }
                      std::reverse(nowLis.begin() , nowLis.end()) ; //vector逆序
                      List.push_back(nowLis) ;
                 }
            }
            sort(List.begin() , List.end()) ;  
            nowLis = List[0] ;
            printf("%d" ,nowLis[0]) ;
            for(j = 1 ;  j < nowLis.size() ; j++)
                    printf(" %d" ,nowLis[j]) ;
            puts("") ;
            printf("%d\n" , ans) ;
      }
      return 0 ;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值