Problem:
Problem C: ホテル探し
Problem Statement
会津合宿に参加予定の高槻さんは、家が貧乏であまりお金を持っていない。彼女は、合宿のためにホテルを探しているが、なるべくお金を節約できるプランにするために、悩み中である。宿泊の合計金額が安くなるホテルの泊まり方を求めて、彼女に教えてあげよう。
宿泊するホテルの候補数は、N個であり、各ホテルをホテル1、ホテル2、...、ホテルNと呼ぶこととする。彼女は、これからD泊分の予約をこれらのホテルから選ぶことにしている。候補のホテルは全て、1泊ごとに宿泊料金が変動することがあるため、入力では各ホテルごとにD泊分の宿泊費が与えられる。
D泊分の宿泊費の合計が最小になるような、ホテルの泊まり方を出力せよ。ただし、D泊全て同じホテルに泊まる必要はないことに注意してほしい。安さのためであれば、彼女は1泊ごとにホテルの移動をすることも考えている。
もし、そのような宿泊方法が複数あるならば、ホテルの移動回数が最小になるような宿泊方法を出力せよ。ホテルの移動回数とは、x泊目(1 <= x < D)の宿泊ホテルとx+1泊目の宿泊ホテルが異なる場合にこれを1回の移動と考え、D泊分足し合わせた値である。
それでも1通りに定まらない場合は、辞書順で最も小さくなるような宿泊方法を出力すること。2つの宿泊ホテル番号の数列 A = {a1, a2, ..., aD} と B = {b1, b2, ..., bD} があったとき、AがBより辞書順で小さいとは、aiがbiと異なるような最初のiについて、aiがbiより小さいときのことを言う。
Input
各データセットは、以下の形式で入力される。
N D
p11 p12 ... p1D
p21 p22 ... p2D
...
pN1 pN2 ... pND
入力は、全て整数である。Nは宿泊候補のホテルの数、Dは宿泊日数である。pijは、ホテルiにおける、j泊目の宿泊費である。
Constraints
1 <= N <= 50
1 <= D <= 50
1 <= pij <= 10000
Output
各データセットに対して、以下の形式で出力せよ。
P M
stay1
stay2
...
stayD
PはD泊分の最小の宿泊費合計、Mは最小のホテル移動回数である。続いて、問題文に指定された条件で宿泊するホテルを決定し、D泊分のホテルの番号を出力せよ。stayi (1 <= stayi <= N)は、i泊目に宿泊するホテルが、ホテルstayiであることを意味する。
Sample Input 1
2 3
3000 6000 3000
4000 5500 4500
Output for the Sample Input 1
11500 2
1
2
1
最小の宿泊費合計は、11500円であり、この合計値を満たせるのは、
1泊目にホテル1に泊まり3000円、2泊目にホテル2に泊まり5500円、3泊目にホテル1に泊まり3000円の方法だけである。ここでは、1泊目と2泊目の間、2泊目と3泊目の間、の合計2回ホテルの移動を行っている。
Sample Input 2
3 4
5500 5500 5500 5500
5480 5780 5980 5980
5500 5500 5500 5500
Output for the Sample Input 2
21980 1
2
1
1
1
このサンプルの宿泊費合計の最小は21980円である。合計をこの価格にするための方法は何通りか存在するが、移動回数を最小にするならば、A = {2, 1, 1, 1}、B = {2, 3, 3, 3}の2通りにしぼられる。この2通りの内、辞書順で最小なものはAであるため、これを出力する。

Submitted solutions:

code_snippet: #include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <string>
#include <cmath>
#include <queue>

using namespace std;

using ll = long long;

//const ll INF = 1LL << 60;
//const ll MINUS_INF = -INF;

const int INF = (1 << 21);
const int MINUS_INF = -INF;

template<class T> inline bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}

template<class T> inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

typedef struct _buil
{
    int x;
    int y;
}st_buil;

// https://onlinejudge.u-aizu.ac.jp/problems/2517

// メイン関数
int main(void)
{
    int N, D;

    cin >> N >> D;

    // ホテルの宿泊数と料金を保持するvector
    vector<vector<int>> hotel(N + 1, vector<int>(D + 1, 0));

    for(int i = 1; i <= N; i++)
    {
        for(int j = 1; j <=D; j++)
        {
            cin >> hotel[i][j];
        }
    }
    
    // 最安値のホテル料金
    vector<int> cost(D + 1, INF);
    // 最小の移動回数
    vector<int> move(D + 1, INF);

    // 最安値の宿泊ルート
    vector<vector<vector<int>>> route(D + 1, vector<vector<int>>(1, vector<int>(1, 0)));

    cost[0] = 0;
    move[0] = 0;
    move[1] = 0;
    route[0][0][0] = 0;

    // 宿泊ルートを検索する
    for(int day = 1; day <= D; day++)
    {
        bool same_hotel = false;

        for(int j = 1; j <= N; j++)
        {
            if( cost[day] >= cost[day - 1] + hotel[j][day] )
            {
                if( cost[day] > cost[day - 1] + hotel[j][day] )
                {
                    // 料金が更新される時は前のルートを消す ( 最低料金が同じ時は消さない )
                    route[day].clear();
                    same_hotel = false;
                }

                cost[day] = cost[day - 1] + hotel[j][day];

                for(int k = 0; k < route[day - 1].size(); k++)
                {
                    vector<int> tmp;
                    copy(route[day - 1][k].begin(), route[day - 1][k].end(), back_inserter(tmp));
                    tmp.push_back(j);
                    route[day].push_back(tmp);

                    int size = tmp.size();

                    if( tmp[size - 2] == tmp[size - 1] )
                    {
                        // 同じホテルに泊まっている
                        same_hotel = true;
                    }
                }
            }
        }

        if( same_hotel == true )
        {
            // 移動回数の更新
            move[day] = move[day - 1];

            vector<vector<int>> save(route[day].size());
           
            for(int i = 0; i < route[day].size(); i++)
            {
                 vector<int> tmp;
                copy(route[day][i].begin(), route[day][i].end(), back_inserter(tmp));
                copy(tmp.begin(), tmp.end(), back_inserter(save[i]));
            }

            route[day].clear();

            for(int i = 0; i < save.size(); i++)
            {
                int pos = save[i].size() - 1;

                if( save[i][pos - 1] == save[i][pos] )
                {
                    // 移動回数が最小になるように経路を残す
                    route[day].push_back(save[i]);
                }
            }
        }
        else
        {
            if( day >= 2 )
            {
                // 移動回数の更新
                move[day] = move[day - 1] + 1;
            }
        }
    }

    int min_num = 0;

    // 辞書順で比較する
    if( route[D].size() > 1 )
    {
        string str_min;

        // 辞書順にするためにstringに変換する
        for(int i = 0; i < route[D].size(); i++)
        {
            string tmp = "";

            for(int j = 0; j < route[D][i].size(); j++)
            {

                tmp += to_string(route[D][i][j]);
            }

            if( i == 0 )
            {
                str_min = tmp;
                min_num = 0;
            }
            else
            {
                if( str_min > tmp )
                {
                    str_min = tmp;
                    min_num = i;
                }
            }
        }
    }

    cout << cost[D] << " " << move[D] << endl;

    for(int j = 1; j < route[D][min_num].size(); j++)
    {
        cout << route[D][min_num][j] << endl;
    }

    return 0;
}
accuracy: 0.8536585365853658
time_ms: 70
memory_kb: 8432
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;

struct Graph{
    int V;
    int E;
    vector<tuple<int,int,int,int>> edges;
    void add(int u,int v,int weight){
        edges.push_back(make_tuple(u,v,weight,1));
    }
    Graph(int v) : V(v){}
};

vector<int> Path(const Graph& G,const int& start,const int& goal){
    vector<vector<pair<int,int>>> adj(G.V),adj2(G.V);
    for(auto t:G.edges)adj[get<0>(t)].push_back(make_pair(get<1>(t),get<2>(t)));
    for(auto t:G.edges)adj2[get<1>(t)].push_back(make_pair(get<0>(t),get<2>(t)));
    int dmin[G.V];
    for(int i = 0;i < G.V;i++)dmin[i] = -1;
    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> pque;
    pque.push(make_pair(0,goal));
    pair<int,int> p;
    while(pque.size()){
        p = pque.top();
        pque.pop();
        if(dmin[p.second] == -1){
            dmin[p.second] = p.first;
            for(auto x:adj2[p.second])if(dmin[x.first] == -1){
                pque.push(make_pair(dmin[p.second]+x.second,x.first));
            }
        }
    }
    int now = start;
    vector<int> ans(1,now);
    while(now != goal){
        sort(adj[now].begin(),adj[now].end());
        for(int i = 0;i < adj[now].size();i++){
            pair<int,int> p = adj[now][i];
            if(dmin[now] == dmin[p.first]+p.second){
                ans.push_back(p.first);
                now = p.first;
                break;
            }
        }
    }
    return ans;
}

int main(){
    int N,D,ans_cost = 0;
    cin >> N >> D;
    vector<vector<int>> v(D);
    vector<vector<int>> p(D,vector<int>(N));
    for(int i = 0;i < N;i++){
        for(int j = 0;j < D;j++){
            cin >> p[j][i];
        }
    }
    swap(N,D);
    for(int i = 0;i < N;i++){
        int MIN = 1e9;
        for(int j = 0;j < D;j++){
            MIN = min(MIN,p[i][j]);
        }
        for(int j = 0;j < D;j++){
            if(p[i][j] == MIN){
                v[i].push_back(j);
            }
        }
        ans_cost += MIN;
    }
    Graph G(N*D+2);
    for(auto x:v[0]){
        G.add(N*D,x,0);
    }
    for(int i = 0;i < N-1;i++){
        for(auto x1:v[i])for(auto x2:v[i+1]){
            G.add(i*D+x1,(i+1)*D+x2,(x1==x2 ? 0 : 1));
        }
    }
    for(auto x:v[N-1]){
        G.add((N-1)*D+x,N*D+1,0);
    }
    G.E = G.edges.size();
    auto ans = Path(G,N*D,N*D+1);
    int ans_change = 0;
    for(int i = 1;i < ans.size()-2;i++){
        ans_change += ans[i]%D != ans[i+1]%D;
    }
    cout << ans_cost << ' ' << ans_change << endl;
    for(auto x:ans){
        if(x < N*D)cout << x%D+1 << endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 8208
final_rank: 10

code_snippet: #include <iostream>
#include <list>
#include <vector>
#include <string>
#include <algorithm>
#include <climits>
using namespace std;

using ll = long long int;



long long int N, M;

int main() {

	cin >> N >> M;
	vector<vector<int>>v(N, vector<int>(M));
	for (auto &i : v) {
		for (auto &j : i)cin >> j;
	}
	vector<vector<int>>dis(N, vector<int>(M, 10000));
	vector<vector<vector<vector<int>>>>dp(M, vector<vector<vector<int>>>(N, vector<vector<int>>(M)));
	for (int i = M - 1; i >= 0; i--) {
		int mi = 100000;
		for (int j = 0; j < N; j++) {
			mi = min(mi, v[j][i]);
		}
		for (int j = 0; j < N; j++) {
			if (mi != v[j][i])continue;
			if (i == M - 1) {
				dp[i][j][0] = { j };
			}
			else {
				for (int k = 0; k < M; k++) {
					for (int l = 0; l < N; l++) {
						if (l != j) {
							if (k - 1 <0 || dp[i + 1][l][k - 1].empty())continue;
							if (dp[i][j][k].empty()) {
								dp[i][j][k] = { j };
								for (auto m : dp[i + 1][l][k - 1])dp[i][j][k].push_back(m);
							}
							else {
								vector<int>comp({ j });
								for (auto m : dp[i + 1][l][k - 1])comp.push_back(m);
								dp[i][j][k] = min(dp[i][j][k], comp);
							}
						}
						else {
							if (dp[i + 1][l][k].empty())continue;
							if (dp[i][j][k].empty()) {
								dp[i][j][k] = { j };
								for (auto m : dp[i + 1][l][k])dp[i][j][k].push_back(m);
							}
							else {
								vector<int>comp({ j });
								for (auto m : dp[i + 1][l][k])comp.push_back(m);
								dp[i][j][k] = min(dp[i][j][k], comp);
							}
						}
					}
				}
			}
		}
	}
	for (int i = 0; i < M; i++) {
		for (int j = 0; j < N; j++) {
			for (int k = 0; k < M; k++) {
				if (dp[i][j][k].empty())continue;
//				cout << i << " " << j << " " << k << endl;
//				for (auto l : dp[i][j][k])cout << l << " ";
//				cout << endl;
			}
		}
	}
	int sum = 0;
	for (int i = 0; i < M; i++) {
		int add = 100000;
		for (int j = 0; j < N; j++) {
			add = min(add, v[j][i]);
		}
		sum += add;
	}
	for (int i = 0; i < M; i++) {
		for (int j = 0; j < N; j++) {
			if (dp[0][j][i].empty())continue;
			cout << sum << " " << i << endl;
			for (auto k : dp[0][j][i])cout << k+1 << endl;
			return 0;
		}
	}
	return 0;
}
accuracy: 1
time_ms: 710
memory_kb: 18992
final_rank: 12

code_snippet: #include <iostream>
#include <list>
#include <vector>
#include <string>
#include <algorithm>
#include <climits>
using namespace std;

using ll = long long int;



long long int N, M;

int main() {

	cin >> N >> M;
	vector<vector<int>>v(N, vector<int>(M));
	for (auto &i : v) {
		for (auto &j : i)cin >> j;
	}
	vector<vector<vector<int>>>dp(M, vector<vector<int>>(N, vector<int>(M, 1000000000)));
	for (int i = 0; i < N; i++) {
		dp[0][i][0] = v[i][0];
	}
	for (int i = 1; i < M; i++) {
		for (int j = 0; j < N; j++) {
			for (int k = 0; k < N; k++) {
				for (int l = 0; l < M - 1; l++) {
					if (j == k)dp[i][k][l] = min(dp[i][k][l], dp[i - 1][j][l] + v[k][i]);
					else dp[i][k][l + 1] = min(dp[i][k][l + 1], dp[i - 1][j][l] + v[k][i]);
				}
			}
		}
	}
	int mi = 100000000;
	int mo = 1000;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			if (mi > dp.back()[i][j]) {
				mi = dp.back()[i][j];
				mo = j;
			}
			if (mi == dp.back()[i][j]) {
				mo = min(mo, j);
			}
		}
	}
	vector<vector<vector<int>>>use(M, vector<vector<int>>(N, vector<int>(M)));
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			if (dp.back()[i][j] == mi&&mo == j)use.back()[i][j] = 1;
			//if (dp.back()[i][j] == mi)use.back()[i][j] = 1;
		}
	}
	for (int i = M - 2; i >= 0; i--) {
		for (int j = 0; j < N; j++) {
			for (int k = 0; k < N; k++) {
				for (int l = 0; l < M - 1; l++) {
					if (j == k) {
						if (dp[i][j][l] + v[k][i + 1] == dp[i + 1][k][l] && use[i + 1][k][l])use[i][j][l] = 1;
					}
					else {
						if (dp[i][j][l] + v[k][i + 1] == dp[i + 1][k][l + 1] && use[i + 1][k][l + 1])use[i][j][l] = 1;
					}
				}
			}
		}
	}
	int cnt = 0;
	vector<int>ans;
	for (int i = 0; i < M; i++) {
		for (int j = 0; j < N; j++) {
			for (int k = 0; k < M; k++) {
				if (use[i][j][k]) {
					ans.push_back(j);
					break;
				}
			}
			if (ans.size() == i + 1)break;
		}
	}
	for (int i = 1; i < ans.size(); i++) {
		if (ans[i] != ans[i - 1])cnt++;
	}
	cout << mi << " " << cnt << endl;
	for (auto i : ans)cout << i + 1 << endl;
	return 0;
}
accuracy: 0.8780487804878049
time_ms: 10
memory_kb: 3920
final_rank: 14

code_snippet: #include <iostream>
#include <list>
#include <vector>
#include <string>
#include <algorithm>
#include <climits>
using namespace std;

using ll = long long int;



long long int N, M;

int main() {

	cin >> N >> M;
	vector<vector<int>>v(N, vector<int>(M));
	for (auto &i : v) {
		for (auto &j : i)cin >> j;
	}
	vector<vector<vector<int>>>dp(M, vector<vector<int>>(N, vector<int>(M, 1000000000)));
	for (int i = 0; i < N; i++) {
		dp[0][i][0] = v[i][0];
	}
	for (int i = 1; i < M; i++) {
		for (int j = 0; j < N; j++) {
			for (int k = 0; k < N; k++) {
				for (int l = 0; l < M - 1; l++) {
					if (j == k)dp[i][k][l] = min(dp[i][k][l], dp[i - 1][j][l] + v[k][i]);
					else dp[i][k][l + 1] = min(dp[i][k][l + 1], dp[i - 1][j][l] + v[k][i]);
				}
			}
		}
	}
	int mi = 100000000;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			mi = min(mi, dp.back()[i][j]);
		}
	}
	vector<vector<vector<int>>>use(M, vector<vector<int>>(N, vector<int>(M)));
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			if (dp.back()[i][j] == mi)use.back()[i][j] = 1;
		}
	}
	for (int i = M - 2; i >= 0; i--) {
		for (int j = 0; j < N; j++) {
			for (int k = 0; k < N; k++) {
				for (int l = 0; l < M - 1; l++) {
					if (j == k) {
						if (dp[i][j][l] + v[k][i + 1] == dp[i + 1][k][l] && use[i + 1][k][l])use[i][j][l] = 1;
					}
					else {
						if (dp[i][j][l] + v[k][i + 1] == dp[i + 1][k][l + 1] && use[i + 1][k][l + 1])use[i][j][l] = 1;
					}
				}
			}
		}
	}
	int cnt = 0;
	vector<int>ans;
	for (int i = 0; i < M; i++) {
		for (int j = 0; j < N; j++) {
			for (int k = 0; k < M; k++) {
				if (use[i][j][k]) {
					ans.push_back(j);
					break;
				}
			}
			if (ans.size() == i + 1)break;
		}
	}
	for (int i = 1; i < ans.size(); i++) {
		if (ans[i] != ans[i - 1])cnt++;
	}
	cout << mi << " " << cnt << endl;
	for (auto i : ans)cout << i + 1 << endl;
	return 0;
}
accuracy: 0.6097560975609756
time_ms: 10
memory_kb: 3852
final_rank: 20

code_snippet: #include <vector>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <tuple>
using namespace std;

const int INF = 1 << 28;
int N, D;
int p[51][51], dp[51][51][51];
tuple<int, int, int> pre[51][51][51];
bool can[51][51][51];

tuple<int, int, int> min_tuple(tuple<int, int, int> A, tuple<int, int, int> B) {
  int a1, a2, a3, b1, b2, b3;
  tie(a1, a2, a3) = A, tie(b1, b2, b3) = B;
  if(a2 < b2) return A;
  return B;
}

int main() {
  cin >> N >> D;
  for(int i=0; i<N; i++) {
    for(int j=0; j<D; j++) {
      cin >> p[i][j];
    }
  }

  fill(dp[0][0], dp[D+1][0], INF);
  const tuple<int, int, int> INIT(INF, INF, INF);
  fill(pre[0][0], pre[D+1][0], INIT);
  for(int i=0; i<N; i++) dp[0][i][0] = 0;
  for(int i=0; i<D; i++) {
    for(int j=0; j<N; j++) {
      for(int k=0; k<=i; k++) {
        if(dp[i][j][k] == INF) continue;
        
        // if(i == D) continue;
        for(int x=0; x<N; x++) {
          int ncost = dp[i][j][k] + p[x][i];
          int nmove = k + (j != x);
          if(dp[i+1][x][nmove] >= ncost) {
            bool strict = (dp[i+1][x][nmove] > ncost);
            dp[i+1][x][nmove] = ncost;

            if(strict) pre[i+1][x][nmove] = make_tuple(i, j, k);
            else pre[i+1][x][nmove] = min_tuple(pre[i+1][x][nmove], make_tuple(i, j, k));
          }
        }
      }
    }
  }

  for(int i=0; i<=D; i++) {
    for(int j=0; j<N; j++) {
      for(int k=0; k<=i; k++) {
        if(dp[i][j][k] == INF) continue;
        // fprintf(stderr, "dp[%d][%d][%d] = %d, ", i, j, k, dp[i][j][k]);
        int a, b, c; tie(a, b, c) = pre[i][j][k];
        // fprintf(stderr, "pre = (%d, %d, %d)\n", a, b, c);
      }
    }
  }

  int min_cost = INF, min_move = INF, min_hotel = INF;
  for(int hotel=0; hotel<N; hotel++) {
    for(int mv=0; mv<D; mv++) {
      int val = dp[D][hotel][mv];
      if(min_cost > val) {
        min_cost = val;
        min_move = mv, min_hotel = hotel;
      }
      else if(min_cost == val) {
        if(min_move > mv) {
          min_move = mv;
          min_hotel = hotel;
        }
        else if(min_move == mv) {
          min_hotel = min(min_hotel, hotel);
        }
      }
    }
  }

  for(int hotel=0; hotel<N; hotel++) {
    if(dp[D][hotel][min_move] == min_cost) {
      can[D][hotel][min_move] = true;
    }
  }

  // cerr << "passed 1" << endl;
  for(int i=D-1; i>=0; i--) {
    for(int j=0; j<N; j++) {
      for(int k=0; k<D; k++) {
        for(int x=0; x<N; x++) {
          // fprintf(stderr, "%lld, %lld, %lld, %lld\n", i, j, k, x);
          int ncost = dp[i][j][k] + p[x][i];
          int nmove = k + (x != j);
          if(dp[i+1][x][nmove] == ncost and can[i+1][x][nmove]) {
            can[i][j][k] = true;
          }
        }
      }
    }
  }

  // cout << "passed" << endl;
  vector<int> ans;
  int cur = -1, mv = 0;
  for(int i=0; i<N; i++) {
    if(can[1][i][0]) {
      cur = i;
      ans.push_back(i);
      break;
    }
  }

  for(int i=1; i<D; i++) {
    for(int x=0; x<N; x++) {
      int nmove = mv + (x != cur);
      if(can[i+1][x][nmove]) {
        cur = x;
        ans.push_back(x);
        mv = nmove;
        break;
      }
    }
  }

  // fprintf(stderr, "min_cost = %d, min_move = %d, min_hotel = %d\n", min_cost, min_move, min_hotel);
  /*
  vector<int> ans;
  int idx = D, hotel = min_hotel, mv = min_move;
  for(; idx > 0; idx--) {
    ans.push_back(hotel);
    int a, b, c; tie(a, b, c) = pre[idx][hotel][mv];
    hotel = b; mv = c;
    // fprintf(stderr, "hotel = %d, mv = %d\n", hotel, mv);
  }
  reverse(ans.begin(), ans.end());
  */

  printf("%d %d\n", min_cost, min_move);
  for(int i=0; i<D; i++) {
    printf("%d\n", ans[i] + 1);
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 5436
final_rank: 9

code_snippet: #include <bits/stdc++.h>
#define GET_MACRO(_1,_2,_3,_4,_5,NAME,...) NAME
#define pr(...) GET_MACRO(__VA_ARGS__,pr5,pr4,pr3,pr2,pr1)(__VA_ARGS__)
#define pr1(a) (#a)<<"="<<(a)
#define pr2(a,b) pr1(a)<<", "<<pr1(b)
#define pr3(a,b,c) pr2(a,b)<<", "<<pr1(c)
#define pr4(a,b,c,d) pr3(a,b,c)<<", "<<pr1(d)
#define pr5(a,b,c,d,e) pr4(a,b,c,d)<<", "<<pr1(e)
#define int long long
#define double long double
using namespace std;
const int N = 100010;
const int INF = 1LL<<55;
const int mod = (1e9)+7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
typedef pair<int,int> P;
typedef long long ll;
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}
ostream& operator<<(ostream& o,P p){return o<<"("<<p.first<<","<<p.second<<")";}
istream& operator>>(istream& i,P &p){return i>>p.first>>p.second;}
ostream& operator<<(ostream& o,vector<auto> &a){int i=0;for(auto t:a)o<<(i++?" ":"")<<t;return o;}
istream& operator>>(istream& i,vector<auto> &a){for(auto &t:a)i>>t;return i;}
void prArr(auto a,string s=" "){int i=0;for(auto t:a)cout<<(i++?s:"")<<t;cout<<endl;}

int count(vector<int> &a){
  int res = 0;
  int n = a.size();
  for(int i=0;i<n-1;i++) res += a[i] != a[i+1];
  return res;
}

vector<int> chmin(vector<int> &a,vector<int> b){
  int ac = count(a), bc = count(b);
  if(ac != bc) return a = ac < bc? a:b;
  
  int n = min(a.size(),b.size());
  for(int i=0;i<n;i++) 
    if(a[i] != b[i]) return a = a[i] < b[i]? a:b;
  
  return a;
}

signed main(){
  int n,D;
  cin>>n>>D;

  vector<vector<int> > A(n,vector<int>(D));
  cin>>A;

  vector<int> C(D,INF);
  for(int d=0;d<D;d++)
    for(int i=0;i<n;i++) Min(C[d], A[i][d]);
  
  const int N = 51;
  vector<int> dp[N]; // day
  for(int i=1;i<N;i++) 
    for(int j=0;j<N;j++) dp[i].push_back(j);
  
    
  for(int d=0;d<D;d++){
      for(int i=0;i<n;i++){
        auto his = dp[d];
        for(int d2=d;d2 < D;d2++){
          if(A[i][d2] != C[d2]) break;
          his.push_back(i);
          chmin(dp[d2+1],his);
        }
      }
  }
  
  vector<int> ans = dp[D];

  int cost = 0;
  for(int i=0;i<D;i++) cost += C[i];
  cout<<cost<<" "<<count(ans)<<endl;
  for(int i=0;i<D;i++) cout<< ans[i]+1 << endl;
      
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3208
final_rank: 3

code_snippet: #include<bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
typedef pair<int,int>P;
typedef vector<int>V;
int MIN[55],idx,sum,idx2,ans;
int n,m,a[55][55];
vector<int> dp[55];
int count(vector<int> &a){
  int cnt = 0;
  int n = a.size();
  for(int i=0;i<n-1;i++){
    if(a[i] != a[i+1]) cnt++;
  }
  return cnt;
}

V chmin(V &a,V b){
  if(count(a) != count(b)) return a = count(a) < count(b)? a:b;
  int n =min(a.size(),b.size());
  for(int i=0;i<n;i++) if(a[i]!=b[i]) return a = a[i]<b[i]? a:b;
  return a;
}

/*int chmin(PV &a, PV b){
  if(a.first != b.first) {
    int res = a.first > b.first;
    a = a.first < b.first? a:b;
    return res;
  }
  
  if(count(a.second) != count(b.second)){
    int res = count(a.second) > count(b.second);
    a = count(a.second) < count(b.second)? a:b;
    return  res;
  }
  
  int n = a.second.size();
  for(int i=0;i<n;i++){
    if(a.second[i] != b.second[i]){
      int res = a.second[i] > b.second[i];
      a = a.second[i] < b.second[i]? a:b;
      return res;
    }
  }
  return 0;
  }*/
int main(){
  r(i,54){
    r(j,55)dp[i+1].push_back(j);
  }
  r(i,55)MIN[i]=1e8;
  cin>>n>>m;
  r(i,n){
    r(j,m){
      cin>>a[i][j];
      MIN[j]=min(MIN[j],a[i][j]);
    }
  }
  r(i,m)ans+=MIN[i];
  r(o,55){
  r(i,n){
    r(j,m){
      int pre=j;
      while(j<m&&MIN[j]==a[i][j])j++;
      for(int k=pre;k<j;k++){
	V v=dp[k];
	for(int l=k+1;l<=j;l++){
	  v.push_back(i);
	  chmin(dp[l],v);
	}
      }
      //if(pre!=j)while(pre<j)dp[pre][j]=max(dp[pre][j],-i),pre++;
    }
  }}
  
  cout<<ans<<' '<<count(dp[m])<<endl;
  r(i,m){
    cout<<dp[m][i]+1<<endl;
  }
}
accuracy: 1
time_ms: 640
memory_kb: 3192
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
int N,D;
int p[60][60];
int dp[60][60][60];
int pre[60][60][60];
const int INF = 1000000000;

int rec(int pos,int x,int y){
  if(dp[pos][x][y]!=-1)return dp[pos][x][y];

  if(y<0){
    return dp[pos][x][y]=INF;
  }
  
  if(x==D){
    return dp[pos][x][y]=(y==0?0:INF);
  }

  int res=INF;
  
  for(int to=0;to<N;to++){
    if(to==pos){
      if(res>rec(to,x+1,y)+p[to][x]){
        res=rec(to,x+1,y)+p[to][x];
        pre[pos][x][y]=to;
      }
    }else{
      if(res>rec(to,x+1,y-1)+p[to][x]){
        res=rec(to,x+1,y-1)+p[to][x];
        pre[pos][x][y]=to;
      }
    }
  }

  return dp[pos][x][y]=res;
}

int main(){
  memset(dp,-1,sizeof(dp));
  memset(pre,-1,sizeof(pre));
      
  cin>>N>>D;
  for(int i=0;i<N;i++)
    for(int j=0;j<D;j++)
      cin>>p[i][j];


  int mini=INF;
  int pos,x=0,y;
  vector<int> ans;
  for(int i=0;i<=D;i++){
    for(int j=0;j<N;j++){
      if(mini > rec(j,0,i)){
        mini=rec(j,0,i);
        pos=j;
        y=i;
      }
    }
  }

  cout<<mini<<' '<<y<<endl;
  
  while(1){
    int to=pre[pos][x][y];

    x++;
    if(to!=pos)y--;
    pos=to;
    if(y<0 || pos<0)break;
    ans.push_back(pos);
  }
  for(int i=0;i<(int)ans.size();i++){
    cout<<ans[i]+1<<endl;
  }

  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4852
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;

const int INF = 1e9;

int N, D, p[55][55], dp[55][55][55];

signed main(){  
  
  cin>>N>>D;
  
  for(int i=0;i<N;i++)
    for(int j=0;j<D;j++) cin>>p[i][D-j-1];
  
  for(int i=0;i<=D;i++)
    for(int j=0;j<N;j++)
      for(int k=0;k<=D;k++) dp[i][j][k] = INF;
  
  for(int i=0;i<N;i++) dp[1][i][0] = p[i][0];

  
  for(int i=1;i<D;i++){
    
    for(int j=0;j<N;j++){

      for(int k=0;k<=D;k++){
	
	if( dp[i][j][k] == INF ) continue;
	
	for(int l=0;l<N;l++){
	  
	  int nk = k;
	  
	  if( j != l ) nk++;
	  
	  dp[i+1][l][nk] = min( dp[i+1][l][nk], dp[i][j][k] + p[l][i] );
	  
	}
	
      }
      
    }
    
  }
  
  int P = INF;
  
  for(int i=0;i<N;i++)
    for(int j=0;j<=D;j++) P = min( P, dp[D][i][j] );
  
  int M = INF;
  
  for(int i=0;i<N;i++)
    for(int j=0;j<=D;j++)
      if( P == dp[D][i][j] ) M = min( M, j );


  cout<<P<<' '<<M<<endl;

  int h;
  
  for(int i=0;i<N;i++)
    for(int j=0;j<=D;j++)
      
      if( P == dp[D][i][j] && M == j ){
	h = i;
	break;
      }
	
  vector<int> ans;
  
  int I = D, x = M;

  ans.push_back( h + 1 );
  
  while( --I ){
    
    for(int i=0;i<N;i++){
      
      if( h == i && dp[I+1][h][x] - p[h][I] == dp[I][i][x] ) break;
      
      if( h != i && x != 0 && dp[I+1][h][x] - p[h][I] == dp[I][i][x-1] ){
	h = i;
	x--;
	break;
      }
      
    }
    
    ans.push_back( h + 1 );
  }
  
  for(auto idx : ans ) cout<<idx<<endl;
  
  return 0;
}
accuracy: 0.8536585365853658
time_ms: 10
memory_kb: 3776
final_rank: 17

code_snippet: #include<bits/stdc++.h>
using namespace std;

const int INF = 1e9;

int N, D, p[55][55], dp[55][55][55];

signed main(){  
  
  cin>>N>>D;
  
  for(int i=0;i<N;i++)
    for(int j=0;j<D;j++) cin>>p[i][D-j-1];
  
  for(int i=0;i<=D;i++)
    for(int j=0;j<N;j++)
      for(int k=0;k<=D;k++) dp[i][j][k] = INF;
  
  for(int i=0;i<N;i++) dp[1][i][0] = p[i][0];

  
  for(int i=1;i<D;i++){
    
    for(int j=0;j<N;j++){

      for(int k=0;k<=D;k++){
	
	if( dp[i][j][k] == INF ) continue;
	
	for(int l=0;l<N;l++){
	  
	  int nk = k;
	  
	  if( j != l ) nk++;
	  
	  dp[i+1][l][nk] = min( dp[i+1][l][nk], dp[i][j][k] + p[l][i] );
	  
	}
	
      }
      
    }
    
  }
  
  int P = INF;
  
  for(int i=0;i<N;i++)
    for(int j=0;j<=D;j++) P = min( P, dp[D][i][j] );
  
  int M = INF;
  
  for(int i=0;i<N;i++)
    for(int j=0;j<=D;j++)
      if( P == dp[D][i][j] ) M = min( M, j );


  cout<<P<<' '<<M<<endl;

  int h;
  
  for(int i=0;i<N;i++)
    for(int j=0;j<=D;j++)
      
      if( P == dp[D][i][j] && M == j ){
	h = i;
	break;
      }
	
  vector<int> ans;
  
  int I = D, x = M;

  ans.push_back( h + 1 );
  
  while( --I ){
    
    for(int i=0;i<N;i++){
      
      if( dp[I+1][h][x] - p[h][I] == dp[I][i][x] ){
	h = i;
	break;
      }
      
      if( dp[I+1][h][x] - p[h][I] == dp[I][i][x-1] ){
	h = i;
	x--;
	break;
      }
      
    }
    
    ans.push_back( h + 1 );
  }
  
  for(auto idx : ans ) cout<<idx<<endl;
  
  return 0;
}
accuracy: 0.6097560975609756
time_ms: 10
memory_kb: 3764
final_rank: 19

code_snippet: #include <stdio.h>
#include <cmath>
#include <math.h>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Info{
	bool operator<(const struct Info &arg)const{
		return sum_move > arg.sum_move;
	}
	int day,current_hotel,sum_move;
	int history[51];
};


int main(){

	int N,D;
	scanf("%d %d",&N,&D);

	int min_cost[D+1];
	for(int day = 1; day <= D; day++)min_cost[day] = BIG_NUM;

	int cost[N+1][D+1];
	for(int hotel = 1; hotel <= N; hotel++){
		for(int day = 1; day <= D; day++){
			scanf("%d",&cost[hotel][day]);
			min_cost[day] = min(min_cost[day],cost[hotel][day]);
		}
	}

	vector<int> MIN_COST_HOTEL[D+1];

	for(int day = 1; day <= D; day++){
		for(int hotel = 1; hotel <= N; hotel++){
			if(cost[hotel][day] == min_cost[day])MIN_COST_HOTEL[day].push_back(hotel);
		}
	}

	int min_move[D+1][N+1];
	for(int day = 1; day <= D; day++){
		for(int hotel = 1; hotel <= N; hotel++){
			min_move[day][hotel] = BIG_NUM;
		}
	}

	priority_queue<Info> Q;
	for(int i = 0; i < MIN_COST_HOTEL[1].size(); i++){
		Info new_info;
		new_info.day = 1;
		new_info.current_hotel = MIN_COST_HOTEL[1][i];
		new_info.sum_move = 0;
		new_info.history[1] = MIN_COST_HOTEL[1][i];
		min_move[1][MIN_COST_HOTEL[1][i]] = 0;
		Q.push(new_info);
	}

	int ans[51],minimum_move = BIG_NUM;
	int ans_index,tmp_index,next_hotel,next_move;

	while(!Q.empty()){

		if(Q.top().day == D){

			if(minimum_move > Q.top().sum_move){
				minimum_move = Q.top().sum_move;
				for(int day = 1; day <= D; day++){
					ans[day] = Q.top().history[day];
				}
			}else if(minimum_move == Q.top().sum_move){

				ans_index = tmp_index = 1;
				while(ans[ans_index] == Q.top().history[tmp_index]){
					ans_index++;
					tmp_index++;
				}
				if(ans[ans_index] > Q.top().history[tmp_index]){
					for(int day = 1; day <= D; day++){
						ans[day] = Q.top().history[day];
					}
				}
			}
			Q.pop();
		}else if(Q.top().sum_move > min_move[Q.top().day][Q.top().current_hotel]){
			Q.pop();
		}else{

			for(int i = 0; i < MIN_COST_HOTEL[Q.top().day+1].size(); i++){
				next_hotel = MIN_COST_HOTEL[Q.top().day+1][i];

				if(next_hotel == Q.top().current_hotel){
					next_move = Q.top().sum_move;
				}else{
					next_move = Q.top().sum_move+1;
				}

				if(min_move[Q.top().day+1][next_hotel] >= next_move){
					min_move[Q.top().day+1][next_hotel] = next_move;
					Info new_info;
					new_info.day = Q.top().day+1;
					new_info.current_hotel = next_hotel;
					new_info.sum_move = next_move;
					for(int k = 1; k <= Q.top().day; k++)new_info.history[k] = Q.top().history[k];
					new_info.history[Q.top().day+1] = next_hotel;
					Q.push(new_info);
				}
			}
			Q.pop();
		}
	}

	int P = 0;
	for(int day = 1; day <= D; day++)P += min_cost[day];

	printf("%d %d\n",P,minimum_move);
	for(int day = 1; day <= D; day++)printf("%d\n",ans[day]);

	return 0;
}
accuracy: 0.8780487804878049
time_ms: 20
memory_kb: 16824
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int (i)=0; (i)<(int)(n); (i)++)
#define all(x) (x).begin(),(x).end()

const int N = 55;
const int INF = 19191919;
int n,d;
int p[N][N];

int dp[N][N][N];
int par[N][N][N];
int ok[N][N][N] = {};

int main(){
  cin >>n >>d;
  rep(i,n)rep(j,d) cin >>p[i][j];
  
  rep(i,N)rep(j,N)rep(k,N)
  {
    dp[i][j][k] = INF;
    par[i][j][k] = INF;
  }
  
  rep(i,n) dp[0][0][i] = 0;
  
  rep(i,d)rep(j,N-1)rep(k,n)
  {
    // next stay
    rep(l,n)
    {
      int nj = j+(k!=l);
      if(dp[i+1][nj][l] > dp[i][j][k]+p[l][i])
      {
        dp[i+1][nj][l] = dp[i][j][k]+p[l][i];
        par[i+1][nj][l] = k;
      }
      else if(dp[i+1][nj][l] == dp[i][j][k]+p[l][i])
      {
        par[i+1][nj][l] = min(par[i+1][nj][l], k);
      }
    }
  }
  
  int P = INF;
  int M = INF;
  rep(i,N)rep(j,n) P = min(P,dp[d][i][j]);
  rep(i,N)rep(j,n)if(dp[d][i][j] == P) M = min(M, i);
  rep(i,n)if(dp[d][M][i] == P) ok[d][M][i] = 1;
  
  for(int i=d; i>=1; --i)rep(j,N)rep(k,n)
  {
    if(!ok[i][j][k]) continue;
    
    // stayed before
    rep(l,n)
    {
      int bj = j - (k!=l);
      if(bj<0) continue;
      
      if(dp[i][j][k] - p[k][i-1] == dp[i-1][bj][l]) ok[i-1][bj][l] = 1;
    }
  }
  
  
  vector<int> ans(d,INF);
  rep(i,n)
  {
    if(!ok[0][0][i]) continue;
     
    vector<int> t(d);
    int now = i;
    int ct = 0;
    
    rep(j,d)
    {
      rep(k,n)
      {
        int nct = ct + (now!=k);
        if(ok[j+1][nct][k])
        {
          t[j] = k;
          ct = nct;
          now = k;
          break;
        }
      }
    }
    
    /*
    printf(" GO %d\n", i);    
    rep(j,d) cout << t[j]+1 << endl;
    */
    ans = min(ans,t);
  }

  cout << P << " " << M << endl;
  rep(i,d) cout << ans[i]+1 << endl;
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4668
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int (i)=0; (i)<(int)(n); (i)++)
#define all(x) (x).begin(),(x).end()

const int N = 55;
const int INF = 19191919;
int n,d;
int p[N][N];

int dp[N][N][N];
int par[N][N][N];

int main(){
  cin >>n >>d;
  rep(i,n)rep(j,d) cin >>p[i][j];
  
  rep(i,N)rep(j,N)rep(k,N)
  {
    dp[i][j][k] = INF;
    par[i][j][k] = INF;
  }
  
  rep(i,n) dp[0][0][i] = 0;
  
  rep(i,d)rep(j,N-1)rep(k,n)
  {
    // next stay
    rep(l,n)
    {
      int nj = j+(k!=l);
      if(dp[i+1][nj][l] > dp[i][j][k]+p[l][i])
      {
        dp[i+1][nj][l] = dp[i][j][k]+p[l][i];
        par[i+1][nj][l] = k;
      }
      else if(dp[i+1][nj][l] == dp[i][j][k]+p[l][i])
      {
        par[i+1][nj][l] = min(par[i+1][nj][l], k);
      }
    }
  }
  
  int P = INF;
  int M = INF;
  rep(i,N)rep(j,n) P = min(P,dp[d][i][j]);
  rep(i,N)rep(j,n)
  {
    if(dp[d][i][j] == P) M = min(M, i);
  }
  
  vector<int> ans(d,INF);
  rep(i,n)
  {
    if(dp[d][M][i] != P) continue;
     
    vector<int> t(d);
    int now = i;
    int ct=M;
    for(int j=d-1; j>=0; --j)
    {
      int nx = par[j+1][ct][now];
      t[j] = now;
      ct -= (now != nx);
      now = nx;
    }
    
    /*
    printf(" GO %d\n", i);    
    rep(j,d) cout << t[j]+1 << endl;
    */
    ans = min(ans,t);
  }

  cout << P << " " << M << endl;
  rep(i,d) cout << ans[i]+1 << endl;
  return 0;
}
accuracy: 0.8780487804878049
time_ms: 10
memory_kb: 4456
final_rank: 15

code_snippet: #include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
struct state {
	vector<int> v; int t;
};
bool operator<(const state& s1, const state& s2) {
	return s1.t != s2.t ? s1.t < s2.t : s1.v < s2.v;
}
int n, m;
int main() {
	cin >> n >> m;
	vector<vector<int> > x(m, vector<int>(n));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) cin >> x[j][i];
	}
	int sum = 0; vector<vector<int> > e(m);
	for (int i = 0; i < m; i++) {
		int z = *min_element(x[i].begin(), x[i].end());
		sum += z;
		for (int j = 0; j < n; j++) {
			if (x[i][j] == z) e[i].push_back(j);
		}
	}
	vector<vector<state> > dp(m, vector<state>(n, state{ vector<int>(), 999999999 }));
	for (int i : e[0]) dp[0][i] = state{ vector<int>({ i }), 0 };
	for (int i = 1; i < m; i++) {
		for (int j : e[i]) {
			for (int k : e[i - 1]) {
				state f = dp[i - 1][k];
				f.v.push_back(j);
				if (j != k) f.t++;
				dp[i][j] = min(dp[i][j], f);
			}
		}
	}
	state ret = *min_element(dp[m - 1].begin(), dp[m - 1].end());
	cout << sum << ' ' << ret.t << endl;
	for (int i = 0; i < m; i++) cout << ret.v[i] + 1 << endl;
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3392
final_rank: 5

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;

//// < "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\a.txt" > "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\b.txt"

struct aa {
	vector<int>stays;
	int change_num;
	int cost;
	aa() :stays(), change_num(0), cost(1e9) {

	}
	aa(const vector<int>&_stays, const int _change_num, const int _cost) :stays(_stays), change_num(_change_num), cost(_cost) {

	}
	
};
bool operator<(const aa&l, const aa&r) {
	if (l.cost == r.cost) {
		if (l.change_num == r.change_num) {
			for (int s = 0; s < l.stays.size(); ++s) {
				if (l.stays[s] == r.stays[s])continue;
				else return l.stays[s] < r.stays[s];
			}
		}
		else {
			return l.change_num < r.change_num;
		}
	}
	else {
		return l.cost < r.cost;
	}
	return true;
}
int main() {
	int N, D; cin >> N >> D;
	vector<vector<int>>costs(D, vector<int>(N));
	for (int i = 0; i < N; ++i) {
		for (int j = 0; j < D; ++j) {
			cin >> costs[j][i];
		}
	}
	vector<vector<aa>>dp(D + 1, vector<aa>(N+1));
	dp[0][N] = aa(vector<int>(), 0, 0);
	

	for (int d = 0; d < D; ++d) {
		for (int h = 0; h <= N; ++h) {
			if (d&&h == N)continue;
			for (int next = 0; next < N; ++next) {
				vector<int>nextstays(dp[d][h].stays);
				nextstays.emplace_back(next);
				const int nextcost = dp[d][h].cost + costs[d][next];
				const int nextchange_num = dp[d][h].change_num + (h != next);
				dp[d + 1][next] = min(dp[d + 1][next], aa(nextstays, nextchange_num, nextcost));
			}
		}
	}
	aa ans = dp[D][0];
	for (int i = 0; i < N; ++i) {
		if (dp[D][i] < ans)ans = dp[D][i];
	}
	cout << ans.cost << " " << ans.change_num-1 << endl;
	for (int i = 0; i < D; ++i) {
		cout << ans.stays[i] + 1 << endl;
	}
	
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3292
final_rank: 4

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int d[50][50], p[50][50], M, n, m;
vector<int>dp[50][50]; int g[50][50];
bool Dainari(vector<int>a, vector<int>b) {
	if (a.size() < b.size())return true;
	if (b.size() > a.size())return false;
	for (int i = 0; i < a.size(); i++) {
		if (a[i] < b[i])return true;
		if (a[i] > b[i])return false;
	}
	return false;
}
int main() {
	cin >> n >> m; int S = 0;
	for (int j = 0; j < n; j++) {
		 for (int i = 0; i < m; i++) { cin >> d[i][j]; M = min(M, d[i][j]); }
	}
	for (int i = 0; i < m; i++) {
		M = 1 << 30; for (int j = 0; j < n; j++) { M = min(d[i][j], M); }
		for (int j = 0; j < n; j++) { if (d[i][j] == M)p[i][j] = 1; }S += M;
	}
	for (int i = 0; i < 50; i++) { for (int j = 0; j < 50; j++)g[i][j] = 1 << 30; }
	for (int i = 0; i < n; i++) { if (p[0][i] == 1) { dp[0][i].push_back(i); g[0][i] = 0; } }
	for (int i = 1; i < m; i++) {
		for (int j = 0; j < n; j++) {
			if (p[i][j] == 0)continue;
			for (int k = 0; k < n; k++) {
				if (p[i - 1][k] == 0)continue;
				vector<int>D = dp[i - 1][k]; D.push_back(j); int L = 1; if (j == k)L = 0;
				if (g[i - 1][k] + L < g[i][j]) { g[i][j] = g[i - 1][k] + L; dp[i][j] = D; }
				else if (g[i - 1][k] + L == g[i][j] && Dainari(D, dp[i][j])) dp[i][j] = D;
			}
		}
	}
	vector<pair<int, vector<int> > >X;
	for (int i = 0; i < n; i++) { X.push_back(make_pair(g[m - 1][i], dp[m - 1][i])); }
	sort(X.begin(), X.end()); vector<int>Y = X[0].second; cout << S << ' ' << X[0].first << endl;
	for (int i = 0; i < m; i++) cout << Y[i] + 1 << endl;
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1612
final_rank: 1

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int d[50][50], p[50][50], M, n, m;
vector<int>dp[50][50]; int g[50][50];
int main() {
	cin >> n >> m; int S = 0;
	for (int j = 0; j < n; j++) {
		 for (int i = 0; i < m; i++) { cin >> d[i][j]; M = min(M, d[i][j]); }
	}
	for (int i = 0; i < m; i++) {
		M = 1 << 30; for (int j = 0; j < n; j++) { M = min(d[i][j], M); }
		for (int j = 0; j < n; j++) { if (d[i][j] == M)p[i][j] = 1; }S += M;
	}
	for (int i = 0; i < 50; i++) { for (int j = 0; j < 50; j++)g[i][j] = 1 << 30; }
	for (int i = 0; i < n; i++) { if (p[0][i] == 1) { dp[0][i].push_back(i); g[0][i] = 0; } }
	for (int i = 1; i < m; i++) {
		for (int j = 0; j < n; j++) {
			if (p[i][j] == 0)continue;
			for (int k = 0; k < n; k++) {
				if (p[i - 1][k] == 0)continue;
				vector<int>D = dp[i - 1][k]; D.push_back(j); int L = 1; if (j == k)L = 0;
				if (g[i - 1][k] + L < g[i][j]) { g[i][j] = g[i - 1][k] + L; dp[i][j] = D; }
				else if (g[i - 1][k] + L < g[i][j] && D < dp[i][j]) dp[i][j] = D;
			}
		}
	}
	vector<pair<int, vector<int> > >X;
	for (int i = 0; i < n; i++) { X.push_back(make_pair(g[m - 1][i], dp[m - 1][i])); }
	sort(X.begin(), X.end()); vector<int>Y = X[0].second; cout << S << ' ' << X[0].first << endl;
	for (int i = 0; i < m; i++) cout << Y[i] + 1 << endl;
	return 0;
}
accuracy: 0.8780487804878049
time_ms: 10
memory_kb: 1608
final_rank: 13

code_snippet: #include<bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
using namespace std;
typedef vector<int> vec;

const int inf = 1e8;
int main(){
  int n,d;
  cin >> n >> d;

  vector<vec> p(n,vec(d));

  vec min_p(d,inf);
  rep(i,n){
    rep(j,d){
      cin >> p[i][j];
      min_p[j] = min(min_p[j], p[i][j]);
    }
  }

  int cost = 0;
  rep(i,d){
    cost += min_p[i];
  }

  vector< vector< pair<int,vec> > > dp(d+1, vector< pair<int,vec> >(n, make_pair(inf, vec(d,n)) ));
  rep(i,n)dp[0][i] = make_pair(0,vec(0));

  rep(i,d){
    rep(j,n){
      rep(k,n){
	if(p[k][i] != min_p[i])continue;

	pair<int,vec> nxt = dp[i][k];
	nxt.second.push_back(k);
	if(j!=k)nxt.first++;

	dp[i+1][j] = min(dp[i+1][j], nxt);
      }
    }
  }

  pair<int,vec> ans = make_pair(inf, vec(d,n));
  rep(i,n){
    ans = min(ans, dp[d][i]);
  }

  cout << cost << " " << ans.first << endl;
  rep(i,ans.second.size()){
    cout << ans.second[i]+1 << endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 1800
final_rank: 2

code_snippet: #include <cstdio>
#include <iostream>
#include <string>
#include <map>
#include <vector>

using namespace std;

const int inf=1<<29;

#define rep(i, n) for(int (i) = 0; (i) < n; (i)++)

int p[55][55];

int dp1[55][55];
int dp2[55][55];

int main(void){
	int n,d;
	cin >> n >> d;
	rep(j,n)rep(i,d) cin >> p[i][j];

	rep(i,55)rep(j,55) dp1[i][j]=dp2[i][j]=inf;
	dp1[0][0]=0;
	dp2[0][0]=0;

	rep(i,d)rep(j,n)rep(k,n){
		int p1=dp1[i][j];
		int p2=dp2[i][j];
		p1+=p[i][k];
		if(i!=0) p2+=(j!=k);
		if(p1<dp1[i+1][k]||(p1==dp1[i+1][k]&&p2<dp2[i+1][k])){
			dp1[i+1][k]=p1;
			dp2[i+1][k]=p2;
		}
	}

	int a1=inf,a2=inf;
	rep(i,n) if(dp1[d][i]<a1||(a1==dp1[d][i]&&dp2[d][i]<a2)) a1=dp1[d][i],a2=dp2[d][i];

	vector<int> ans;

	int c1=0,c2=0,c3=-1;
	for(int a=0;a<=d;++a){
		for(int b=0;b<n;++b){
			int n1=c1+p[a][b];
			int n2=c2;
			if(a!=0) n2+=(b!=c3);
			int n3=b;
			rep(i,55)rep(j,55) dp1[i][j]=dp2[i][j]=inf;
			dp1[a+1][b]=n1;
			dp2[a+1][b]=n2;
			for(int i=a+1;i<d;++i)rep(j,n)rep(k,n){
				int p1=dp1[i][j];
				int p2=dp2[i][j];
				p1+=p[i][k];
				if(i!=0) p2+=(j!=k);
				if(p1<dp1[i+1][k]||(p1==dp1[i+1][k]&&p2<dp2[i+1][k])){
					dp1[i+1][k]=p1;
					dp2[i+1][k]=p2;
				}
			}
			int t1=inf,t2=inf;
			rep(i,n) if(dp1[d][i]<t1||(t1==dp1[d][i]&&dp2[d][i]<t2)) t1=dp1[d][i],t2=dp2[d][i];
			if(t1==a1&&t2==a2){
				ans.push_back(b+1);
				c1=n1,c2=n2,c3=n3;
				break;
			}
		}
	}
	cout << a1 << " " << a2 << endl;
	rep(i,d) cout << ans[i] << endl;
	return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 1260
final_rank: 6