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 ;
}