Problem:
Maze & Items
Maze & Items is a puzzle game in which the player tries to reach the goal while collecting items. The maze consists of $W \times H$ grids, and some of them are inaccessible to the player depending on the items he/she has now. The score the player earns is defined according to the order of collecting items. The objective of the game is, after starting from a defined point, to collect all the items using the least number of moves before reaching the goal. There may be multiple routes that allow the least number of moves. In that case, the player seeks to maximize his/her score.
One of the following symbols is assigned to each of the grids. You can move to one of the neighboring grids (horizontally or vertically, but not diagonally) in one time, but you cannot move to the area outside the maze.
Symbol
Description
.
Always accessible
#
Always inaccessible
Number
0
,
1
,..,
9
Always accessible and an item (with its specific number) is located in the grid.
Capital letter
A
,
B
, ...,
J
Accessible only when the player does NOT have the corresponding item. Each of
A
,
B
, ...,
J
takes a value from
0
to
9
.
Small letter
a
,
b
, ...,
j
Accessible only when the player DOES have the corresponding item. Each of
a
,
b
, ...,
j
takes one value from
0
to
9
.
S
Starting grid. Always accessible.
T
Goal grid. Always accessible.
The player fails to complete the game if he/she has not collected all the items before reaching the goal. When entering a grid in which an item is located, it’s the player’s option to collect it or not. The player must keep the item once he/she collects it, and it disappears from the maze.
Given the state information of the maze and a table that defines the collecting order dependent scores, make a program that works out the minimum number of moves required to collect all the items before reaching the goal, and the maximum score gained through performing the moves.
Input
The input is given in the following format.
$W$ $H$
$row_1$
$row_2$
...
$row_H$
$s_{00}$ $s_{01}$ ... $s_{09}$
$s_{10}$ $s_{11}$ ... $s_{19}$
...
$s_{90}$ $s_{91}$ ... $s_{99}$
The first line provides the number of horizontal and vertical grids in the maze $W$ ($4 \leq W \leq 1000$) and $H$ ($4 \leq H \leq 1000$). Each of the subsequent $H$ lines provides the information on the grid $row_i$ in the $i$-th row from the top of the maze, where $row_i$ is a string of length $W$ defined in the table above. A letter represents a grid. Each of the subsequent 10 lines provides the table that defines collecting order dependent scores. An element in the table $s_{ij}$ ($0 \leq s_{ij} \leq 100$) is an integer that defines the score when item $j$ is collected after the item $i$ (without any item between them). Note that $s_{ii} = 0$.
The grid information satisfies the following conditions:
Each of
S
,
T
,
0
,
1
, ...,
9
appears in the maze once and only once.
Each of
A
,
B
, ...,
J
,
a
,
b
, ...,
j
appears in the maze no more than once.
Output
Output two items in a line sepa
...(truncated)

Submitted solutions:

code_snippet: // AOJ #400 Maze and Items
// 2025.3.7

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

struct Edge { int d, req; };
struct State { int r, c, req, d; };

int W, H;
pair<int,int> keyPos[12];
int scoreTab[10][10];
vector<Edge> edgeCandidate[12][12];
vector<string> maze;

inline int cellId(int r, int c) { return r * W + c; }
inline bool isLetter(char ch) { return (ch >= 'A' && ch <= 'J') || (ch >= 'a' && ch <= 'j'); }
inline int letterId(char ch) {
    if(ch >= 'A' && ch <= 'J') return ch - 'A';
    return ch - 'a';
}
inline bool subset(int a, int b) { return (a & ~b) == 0; }

void bfsForKey(int k) {
    int sr = keyPos[k].first, sc = keyPos[k].second;
    int tot = W * H;
    vector<vector<pair<int,int>>> vis(tot);
    deque<State> dq;
    dq.push_back({sr, sc, 0, 0});
    vis[cellId(sr,sc)].push_back({0, 0});

    int dr[4] = {1,-1,0,0}, dc[4] = {0,0,1,-1};
    const int mask = (1<<10)-1;

    while(!dq.empty()){
        State s = dq.front(); dq.pop_front();
        int id = cellId(s.r, s.c);
        char ch = maze[s.r][s.c];
        if((ch=='S' || ch=='T' || (ch>='0' && ch<='9')) && !(s.r==sr && s.c==sc)){
            int idx = -1;
            if(ch=='S') idx = 0;
            else if(ch=='T') idx = 11;
            else idx = (ch - '0') + 1;
            edgeCandidate[k][idx].push_back({s.d, s.req});
        }

        for(int i=0; i<4; i++){
            int nr = s.r + dr[i], nc = s.c + dc[i];
            if(nr < 0 || nr >= H || nc < 0 || nc >= W) continue;
            char ncCh = maze[nr][nc];
            if(ncCh=='#') continue;

            int nreq = s.req;
            if(isLetter(ncCh)){
                int idd = letterId(ncCh);
                int r0 = nreq & mask, r1 = nreq >> 10;
                if(ncCh >= 'A' && ncCh <= 'J'){
                    if(r1 & (1<<idd)) continue;
                    r0 |= (1<<idd);
                } else {
                    if(r0 & (1<<idd)) continue;
                    r1 |= (1<<idd);
                }
                nreq = (r1 << 10) | r0;
            }

            int nd = s.d + 1;
            int cid = cellId(nr, nc);

            bool skip = false;
            for(auto &p : vis[cid]){
                int r_old = p.first, d_old = p.second;
                int r0_old = r_old & mask, r1_old = r_old >> 10;
                int r0_new = nreq & mask, r1_new = nreq >> 10;
                if(d_old <= nd && subset(r0_old, r0_new) && subset(r1_old, r1_new)){
                    skip = true;
                    break;
                }
            }
            if(skip) continue;

            for(auto it = vis[cid].begin(); it != vis[cid].end(); ){
                int r_old = it->first, d_old = it->second;
                int r0_old = r_old & mask, r1_old = r_old >> 10;
                int r0_new = nreq & mask, r1_new = nreq >> 10;
                if(nd <= d_old && subset(r0_new, r0_old) && subset(r1_new, r1_old))
                    it = vis[cid].erase(it);
                else it++;
            }
            vis[cid].push_back({nreq, nd});
            dq.push_back({nr, nc, nreq, nd});
        }
    }
}

struct StateDP { int m, v, d, sc; };

struct cmpDP {
    bool operator()(const StateDP &a, const StateDP &b) const {
        if(a.d != b.d) return a.d > b.d;
        return a.sc < b.sc;
    }
};

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> W >> H;
    maze.resize(H);
    for (int i=0; i<H; i++) cin >> maze[i];
    for (int i=0; i<12; i++) keyPos[i] = {-1,-1};
    for (int r=0; r<H; r++){
        for (int c=0; c<W; c++){
            char ch = maze[r][c];
            if(ch=='S') keyPos[0] = {r,c};
            else if(ch=='T') keyPos[11] = {r,c};
            else if(ch>='0' && ch<='9'){
                int id = ch - '0';
                keyPos[id+1] = {r,c};
            }
        }
    }
    for (int i=0; i<10; i++){
        for (int j=0; j<10; j++) cin >> scoreTab[i][j];
    }
    for (int i=0; i<12; i++) bfsForKey(i);
    const int FULL = (1<<10)-1;
    const int INF = 1e9;
    vector<vector<pair<int,int>>> dp(1<<10, vector<pair<int,int>>(12, {INF, -1000000000}));
    dp[0][0] = {0, 0};

    priority_queue<StateDP, vector<StateDP>, cmpDP> pq;
    pq.push({0, 0, 0, 0});
    while(!pq.empty()){
        auto st = pq.top(); pq.pop();
        int m = st.m, v = st.v, d = st.d, sc = st.sc;
        if(d != dp[m][v].first || sc != dp[m][v].second) continue;
        if(v==11 && m==FULL){
            cout << d << " " << sc << endl;
            return 0;
        }

        for (int nv = 1; nv <= 10; nv++){
            int bit = nv - 1;
            if(m & (1<<bit)) continue;
            for(auto &ed : edgeCandidate[v][nv]){
                int r0 = ed.req & ((1<<10)-1), r1 = ed.req >> 10;
                if((m & r1) != r1) continue;
                if(((~m) & r0) != r0) continue;
                int nd = d + ed.d;
                int nsc = sc;
                if(v >= 1) nsc += scoreTab[v-1][bit];
                int nm = m | (1<<bit);
                if(nd < dp[nm][nv].first || (nd == dp[nm][nv].first && nsc > dp[nm][nv].second)){
                    dp[nm][nv] = {nd, nsc};
                    pq.push({nm, nv, nd, nsc});
                }
            }
        }
        if(m == FULL){
            for(auto &ed : edgeCandidate[v][11]){
                int r0 = ed.req & ((1<<10)-1), r1 = ed.req >> 10;
                if((m & r1) != r1) continue;
                if(((~m) & r0) != r0) continue;
                int nd = d + ed.d;
                int nsc = sc;
                if(nd < dp[m][11].first || (nd == dp[m][11].first && nsc > dp[m][11].second)){
                    dp[m][11] = {nd, nsc};
                    pq.push({m, 11, nd, nsc});
                }
            }
        }
    }
    cout << -1 << endl;
    return 0;
}
accuracy: 1
time_ms: 640
memory_kb: 43580
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define overload(a,b,c,d,...) d
#define rep1(i,n) for(ll i=0;i<(ll)n;++i)
#define rep2(i,l,r) for(ll i=(ll)l;i<(ll)r;++i)
#define rep(...) overload(__VA_ARGS__,rep2,rep1)(__VA_ARGS__)
#define rrep1(i,n) for(ll i=(ll)(n)-1;i>=0;--i)
#define rrep2(i,l,r) for(ll i=(ll)(r)-1;i>=(ll)l;--i)
#define rrep(...) overload(__VA_ARGS__,rrep2,rrep1)(__VA_ARGS__)
#define all(x) (x).begin(),(x).end()
#define eb emplace_back
static constexpr int dx[]={1,-1,0,0},dy[]={0,0,1,-1};
using vl=vector<ll>;
template<typename T,typename U>
bool chmin(T&a,const U&b){return (a>b?a=b,true:false);}
template<typename T,typename U>
bool chmax(T&a,const U&b){return (a<b?a=b,true:false);}
int main(){
	ll w,h;cin>>w>>h;
	vector<pair<int,int>>digits(10,{-1,-1}),little(10,{-1,-1}),large(10,{-1,-1});
	pair<int,int>start,goal;
	vector<string>s(h);
	for(auto&e:s)cin>>e;
	vector<vector<int>>points(10,vector<int>(10));
	for(auto&vec:points)for(auto&e:vec)cin>>e;
	rep(i,h)rep(j,w){
		if(s[i][j]>='0'&&s[i][j]<='9')digits[s[i][j]-'0']={i,j};
		if(s[i][j]>='a'&&s[i][j]<='j')little[s[i][j]-'a']={i,j};
		if(s[i][j]>='A'&&s[i][j]<='J')large[s[i][j]-'A']={i,j};
		if(s[i][j]=='S')start={i,j};
		if(s[i][j]=='T')goal={i,j};
	}
	map<pair<int,int>,int>mp;
	rep(i,10)mp[digits[i]]=i;
	rep(i,10)mp[little[i]]=i+10;
	rep(i,10)mp[large[i]]=i+20;
	mp[start]=30,mp[goal]=31;
	vector<vector<vector<int>>>dist(12,vector<vector<int>>(12,vector<int>(1<<10,1e9)));
	{
		auto bfs=[&](int x1,int y1)->vector<int> {
			vector<int>res(32,1e9);
			if(x1==-1||y1==-1)return res;
			res[mp[{x1,y1}]]=0;
			queue<array<int,3>>que;
			que.emplace(array<int,3>{x1,y1,0});
			vector<vector<bool>>vis(h,vector<bool>(w,false));
			vis[x1][y1]=true;
			while(!que.empty()){
				auto [x,y,nd]=que.front();que.pop();
				rep(dir,4){
					int nx=x+dx[dir],ny=y+dy[dir];
					if(nx<0||nx>=h||ny<0||ny>=w)continue;
					if(s[nx][ny]=='.'||s[nx][ny]=='S'||s[nx][ny]=='T'||(s[nx][ny]>='0'&&s[nx][ny]<='9')){
						if(!vis[nx][ny]){
							if(mp.count({nx,ny}))res[mp[{nx,ny}]]=nd+1;
							vis[nx][ny]=true;
							que.emplace(array<int,3>{nx,ny,nd+1});
						}
					}
					else if(s[nx][ny]!='#'&&mp.count({nx,ny})){
						chmin(res[mp[{nx,ny}]],nd+1);
					}
				}
			}
			return res;
		};
		vector<vector<int>>dis(32,vector<int>(32,1e9));
		rep(i,10)dis[i]=bfs(digits[i].first,digits[i].second);
		rep(i,10)dis[i+10]=bfs(little[i].first,little[i].second);
		rep(i,10)dis[i+20]=bfs(large[i].first,large[i].second);
		dis[30]=bfs(start.first,start.second);
		dis[31]=bfs(goal.first,goal.second);
		rep(i,10){
			rep(bit,1<<10)if((bit>>i)&1){
				vector<int>cost(32,1e9);
				cost[i]=0;
				priority_queue<pair<int,int>,vector<pair<int,int>>,greater<>>pq;
				pq.emplace(0,i);
				while(!pq.empty()){
					auto [d,v]=pq.top();pq.pop();
					if(d!=cost[v])continue;
					rep(u,32){
						if(10<=u&&u<=19){
							if(!((bit>>(u-10))&1))continue;
						}
						if(20<=u&&u<=29){
							if((bit>>(u-20))&1)continue;
						}
						if(chmin(cost[u],d+dis[v][u]))pq.emplace(cost[u],u);
					}
				}
				rep(j,10)dist[i][j][bit]=cost[j];
				dist[i][10][bit]=cost[30];
				dist[i][11][bit]=cost[31];
			}
		}
		rep(i,30,32){		
			rep(bit,1<<10){
				vector<int>cost(32,1e9);
				cost[i]=0;
				priority_queue<pair<int,int>,vector<pair<int,int>>,greater<>>pq;
				pq.emplace(0,i);
				while(!pq.empty()){
					auto [d,v]=pq.top();pq.pop();
					if(d!=cost[v])continue;
					rep(u,32){
						if(10<=u&&u<=19){
							if(!((bit>>(u-10))&1))continue;
						}
						if(20<=u&&u<=29){
							if((bit>>(u-20))&1)continue;
						}
						if(chmin(cost[u],d+dis[v][u]))pq.emplace(cost[u],u);
					}
				}
				rep(j,10)dist[i-20][j][bit]=cost[j];
				dist[i-20][10][bit]=cost[30];
				dist[i-20][11][bit]=cost[31];
			}
		}
	}
	ll ansd=1e9,ansp=0;
	vector<int>ord(10);
	iota(all(ord),0);
	do{
		ll nowd=0,nowp=0;
		int bit=0;
		nowd+=dist[10][ord[0]][bit];
		for(int i=0;i<9;++i){
			bit|=1<<ord[i];
			nowd+=dist[ord[i]][ord[i+1]][bit];
			nowp+=points[ord[i]][ord[i+1]];
		}
		bit|=1<<ord[9];
		nowd+=dist[ord[9]][11][bit];
		if(nowd<ansd){
			ansd=nowd,ansp=nowp;
		}
		else if(nowd==ansd&&ansp<nowp){
			ansp=nowp;
		}
	}while(next_permutation(all(ord)));
	if(ansd>=(int)1e9){
		cout<<-1<<endl;
		return 0;
	}
	cout<<ansd<< " "<<ansp<<endl;
}
accuracy: 1
time_ms: 590
memory_kb: 6020
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define overload(a,b,c,d,...) d
#define rep1(i,n) for(ll i=0;i<(ll)n;++i)
#define rep2(i,l,r) for(ll i=(ll)l;i<(ll)r;++i)
#define rep(...) overload(__VA_ARGS__,rep2,rep1)(__VA_ARGS__)
#define rrep1(i,n) for(ll i=(ll)(n)-1;i>=0;--i)
#define rrep2(i,l,r) for(ll i=(ll)(r)-1;i>=(ll)l;--i)
#define rrep(...) overload(__VA_ARGS__,rrep2,rrep1)(__VA_ARGS__)
#define all(x) (x).begin(),(x).end()
#define eb emplace_back
static constexpr int dx[]={1,-1,0,0},dy[]={0,0,1,-1};
using vl=vector<ll>;
template<typename T,typename U>
bool chmin(T&a,const U&b){return (a>b?a=b,true:false);}
template<typename T,typename U>
bool chmax(T&a,const U&b){return (a<b?a=b,true:false);}
int main(){
	ll w,h;cin>>w>>h;
	vector<pair<int,int>>digits(10,{-1,-1}),little(10,{-1,-1}),large(10,{-1,-1});
	pair<int,int>start,goal;
	vector<string>s(h);
	for(auto&e:s)cin>>e;
	vector<vector<int>>points(10,vector<int>(10));
	for(auto&vec:points)for(auto&e:vec)cin>>e;
	rep(i,h)rep(j,w){
		if(s[i][j]>='0'&&s[i][j]<='9')digits[s[i][j]-'0']={i,j};
		if(s[i][j]>='a'&&s[i][j]<='j')little[s[i][j]-'a']={i,j};
		if(s[i][j]>='A'&&s[i][j]<='J')large[s[i][j]-'A']={i,j};
		if(s[i][j]=='S')start={i,j};
		if(s[i][j]=='T')goal={i,j};
	}
	map<pair<int,int>,int>mp;
	rep(i,10)mp[digits[i]]=i;
	rep(i,10)mp[little[i]]=i+10;
	rep(i,10)mp[large[i]]=i+20;
	mp[start]=30,mp[goal]=31;
	vector<vector<vector<int>>>dist(12,vector<vector<int>>(12,vector<int>(1<<10,1e9)));
	{
		auto bfs=[&](int x1,int y1)->vector<int> {
			vector<int>res(32,1e9);
			if(x1==-1||y1==-1)return res;
			res[mp[{x1,y1}]]=0;
			queue<array<int,3>>que;
			que.emplace(array<int,3>{x1,y1,0});
			vector<vector<bool>>vis(h,vector<bool>(w,false));
			vis[x1][y1]=true;
			while(!que.empty()){
				auto [x,y,nd]=que.front();que.pop();
				rep(dir,4){
					int nx=x+dx[dir],ny=y+dy[dir];
					if(nx<0||nx>=h||ny<0||ny>=w)continue;
					if(s[nx][ny]=='.'||s[nx][ny]=='S'||s[nx][ny]=='T'||(s[nx][ny]>='0'&&s[nx][ny]<='9')){
						if(!vis[nx][ny]){
							if(mp.count({nx,ny}))res[mp[{nx,ny}]]=nd+1;
							vis[nx][ny]=true;
							que.emplace(array<int,3>{nx,ny,nd+1});
						}
					}
					else if(s[nx][ny]!='#'&&mp.count({nx,ny})){
						chmin(res[mp[{nx,ny}]],nd+1);
					}
				}
			}
			return res;
		};
		vector<vector<int>>dis(32,vector<int>(32,1e9));
		rep(i,10)dis[i]=bfs(digits[i].first,digits[i].second);
		rep(i,10)dis[i+10]=bfs(little[i].first,little[i].second);
		rep(i,10)dis[i+20]=bfs(large[i].first,large[i].second);
		dis[30]=bfs(start.first,start.second);
		dis[31]=bfs(goal.first,goal.second);
		rep(i,10){
			rep(bit,1<<10)if((bit>>i)&1){
				vector<int>cost(32,1e9);
				cost[i]=0;
				priority_queue<pair<int,int>,vector<pair<int,int>>,greater<>>pq;
				pq.emplace(0,i);
				while(!pq.empty()){
					auto [d,v]=pq.top();pq.pop();
					if(d!=cost[v])continue;
					rep(u,32){
						if(10<=u&&u<=19){
							if(!((bit>>(u-10))&1))continue;
						}
						if(20<=u&&u<=29){
							if((bit>>(u-20))&1)continue;
						}
						if(chmin(cost[u],d+dis[v][u]))pq.emplace(cost[u],u);
					}
				}
				rep(j,10)dist[i][j][bit]=cost[j];
				dist[i][10][bit]=cost[30];
				dist[i][11][bit]=cost[31];
			}
		}
		rep(i,30,32){		
			rep(bit,1<<10){
				vector<int>cost(32,1e9);
				cost[i]=0;
				priority_queue<pair<int,int>,vector<pair<int,int>>,greater<>>pq;
				pq.emplace(0,i);
				while(!pq.empty()){
					auto [d,v]=pq.top();pq.pop();
					if(d!=cost[v])continue;
					rep(u,32){
						if(10<=u&&u<=19){
							if(!((bit>>(u-10))&1))continue;
						}
						if(20<=u&&u<=29){
							if((bit>>(u-20))&1)continue;
						}
						if(chmin(cost[u],d+dis[v][u]))pq.emplace(cost[u],u);
					}
				}
				rep(j,10)dist[i-20][j][bit]=cost[j];
				dist[i-20][10][bit]=cost[30];
				dist[i-20][11][bit]=cost[31];
			}
		}
	}
	ll ansd=1e9,ansp=0;
	vector<int>ord(10);
	iota(all(ord),0);
	do{
		ll nowd=0,nowp=0;
		int bit=0;
		nowd+=dist[10][ord[0]][bit];
		for(int i=0;i<9;++i){
			bit|=1<<ord[i];
			nowd+=dist[ord[i]][ord[i+1]][bit];
			nowp+=points[ord[i]][ord[i+1]];
		}
		bit|=1<<ord[9];
		nowd+=dist[ord[9]][11][bit];
		if(nowd<ansd){
			ansd=nowd,ansp=nowp;
		}
		else if(ansp<nowp)ansp=nowp;
	}while(next_permutation(all(ord)));
	if(ansd>=(int)1e9){
		cout<<-1<<endl;
		return 0;
	}
	cout<<ansd<< " "<<ansp<<endl;
}
accuracy: 0.09090909090909091
time_ms: 60
memory_kb: 3792
final_rank: 17

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define overload(a,b,c,d,...) d
#define rep1(i,n) for(ll i=0;i<(ll)n;++i)
#define rep2(i,l,r) for(ll i=(ll)l;i<(ll)r;++i)
#define rep(...) overload(__VA_ARGS__,rep2,rep1)(__VA_ARGS__)
#define rrep1(i,n) for(ll i=(ll)(n)-1;i>=0;--i)
#define rrep2(i,l,r) for(ll i=(ll)(r)-1;i>=(ll)l;--i)
#define rrep(...) overload(__VA_ARGS__,rrep2,rrep1)(__VA_ARGS__)
#define all(x) (x).begin(),(x).end()
#define eb emplace_back
static constexpr int dx[]={1,-1,0,0},dy[]={0,0,1,-1};
using vl=vector<ll>;
template<typename T,typename U>
bool chmin(T&a,const U&b){return (a>b?a=b,true:false);}
template<typename T,typename U>
bool chmax(T&a,const U&b){return (a<b?a=b,true:false);}
int main(){
	ll w,h;cin>>w>>h;
	vector<pair<int,int>>digits(10,{-1,-1}),little(10,{-1,-1}),large(10,{-1,-1});
	pair<int,int>start,goal;
	vector<string>s(h);
	for(auto&e:s)cin>>e;
	vector<vector<int>>points(10,vector<int>(10));
	for(auto&vec:points)for(auto&e:vec)cin>>e;
	rep(i,h)rep(j,w){
		if(s[i][j]>='0'&&s[i][j]<='9')digits[s[i][j]-'0']={i,j};
		if(s[i][j]>='a'&&s[i][j]<='j')little[s[i][j]-'a']={i,j};
		if(s[i][j]>='A'&&s[i][j]<='J')large[s[i][j]-'A']={i,j};
		if(s[i][j]=='S')start={i,j};
		if(s[i][j]=='T')goal={i,j};
	}
	map<pair<int,int>,int>mp;
	rep(i,10)mp[digits[i]]=i;
	rep(i,10)mp[little[i]]=i+10;
	rep(i,10)mp[large[i]]=i+20;
	mp[start]=30,mp[goal]=31;
	vector<vector<vector<int>>>dist(12,vector<vector<int>>(12,vector<int>(1<<10,1e9)));
	{
		auto bfs=[&](int x1,int y1)->vector<int> {
			vector<int>res(32,1e9);
			if(x1==-1||y1==-1)return res;
			res[mp[{x1,y1}]]=0;
			queue<array<int,3>>que;
			que.emplace(array<int,3>{x1,y1,0});
			vector<vector<bool>>vis(h,vector<bool>(w,false));
			vis[x1][y1]=true;
			while(!que.empty()){
				auto [x,y,nd]=que.front();que.pop();
				rep(dir,4){
					int nx=x+dx[dir],ny=y+dy[dir];
					if(nx<0||nx>=h||ny<0||ny>=w)continue;
					if(s[nx][ny]=='.'||s[nx][ny]=='S'||s[nx][ny]=='T'){
						if(!vis[nx][ny]){
							if(mp.count({nx,ny}))res[mp[{nx,ny}]]=nd+1;
							vis[nx][ny]=true;
							que.emplace(array<int,3>{nx,ny,nd+1});
						}
					}
					else if(s[nx][ny]!='#'&&mp.count({nx,ny})){
						chmin(res[mp[{nx,ny}]],nd+1);
					}
				}
			}
			return res;
		};
		vector<vector<int>>dis(32,vector<int>(32,1e9));
		rep(i,10)dis[i]=bfs(digits[i].first,digits[i].second);
		rep(i,10)dis[i+10]=bfs(little[i].first,little[i].second);
		rep(i,10)dis[i+20]=bfs(large[i].first,large[i].second);
		dis[30]=bfs(start.first,start.second);
		dis[31]=bfs(goal.first,goal.second);
		rep(i,10){
			rep(bit,1<<10)if((bit>>i)&1){
				vector<int>cost(32,1e9);
				cost[i]=0;
				priority_queue<pair<int,int>,vector<pair<int,int>>,greater<>>pq;
				pq.emplace(0,i);
				while(!pq.empty()){
					auto [d,v]=pq.top();pq.pop();
					if(d!=cost[v])continue;
					rep(u,32){
						if(10<=u&&u<=19){
							if(!((bit>>(u-10))&1))continue;
						}
						if(20<=u&&u<=29){
							if((bit>>(u-20))&1)continue;
						}
						if(chmin(cost[u],d+dis[v][u])){
							if((10<=u&&u<=31)||(u<10&&((bit>>u)&1))){
								pq.emplace(cost[u],u);
							}
						}
					}
				}
				rep(j,10)dist[i][j][bit]=cost[j];
				dist[i][10][bit]=cost[30];
				dist[i][11][bit]=cost[31];
			}
		}
		rep(i,30,32){		
			rep(bit,1<<10){
				vector<int>cost(32,1e9);
				cost[i]=0;
				priority_queue<pair<int,int>,vector<pair<int,int>>,greater<>>pq;
				pq.emplace(0,i);
				while(!pq.empty()){
					auto [d,v]=pq.top();pq.pop();
					if(d!=cost[v])continue;
					rep(u,32){
						if(10<=u&&u<=19){
							if(!((bit>>(u-10))&1))continue;
						}
						if(20<=u&&u<=29){
							if((bit>>(u-20))&1)continue;
						}
						if(chmin(cost[u],d+dis[v][u])){
							if((10<=u&&u<=31)||(u<10&&((bit>>u)&1))){
								//if(u<10)cerr<<u<<endl;
								pq.emplace(cost[u],u);
							}
						}
					}
				}
				rep(j,10)dist[i-20][j][bit]=cost[j];
				dist[i-20][10][bit]=cost[30];
				dist[i-20][11][bit]=cost[31];
			}
		}
	}
	ll ansd=1e9,ansp=0;
	vector<int>ord(10);
	iota(all(ord),0);
	do{
		ll nowd=0,nowp=0;
		int bit=0;
		nowd+=dist[10][ord[0]][bit];
		for(int i=0;i<9;++i){
			bit|=1<<ord[i];
			nowd+=dist[ord[i]][ord[i+1]][bit];
			nowp+=points[ord[i]][ord[i+1]];
		}
		bit|=1<<ord[9];
		nowd+=dist[ord[9]][11][bit];
		if(nowd<ansd){
			ansd=nowd,ansp=nowp;
		}
		else if(ansp<nowp)ansp=nowp;
	}while(next_permutation(all(ord)));
	if(ansd>=(int)1e9){
		cout<<-1<<endl;
		return 0;
	}
	cout<<ansd<< " "<<ansp<<endl;
}
accuracy: 0.09090909090909091
time_ms: 60
memory_kb: 3872
final_rank: 18

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

using ll = long long;

constexpr int inf = 1000000000;

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	
	int W, H;
	cin >> W >> H;
	vector<char> grid(H * W);
	for (int i = 0; i < H * W; ++i) {
		cin >> grid[i];
	}
	vector score(10, vector(10, 0));
	for (int i = 0; i < 10; ++i) {
		for (int j = 0; j < 10; ++j) {
			cin >> score[i][j];
		}
	}

	const int V = 32;
	std::map<char, int> id;
	for (int i = 0; i < 10; ++i) {
		id['0' + i] = i +  0;
		id['a' + i] = i + 10;
		id['A' + i] = i + 20;
	}
	id['S'] = 30;
	id['T'] = 31;

	vector graph(V, vector(V, inf));
	for (int src = 0; src < H * W; ++src) {
		if (grid[src] == '.' or grid[src] == '#') {
			continue;
		}

		vector<int> dist(H * W, inf);
		std::queue<int> que;
		const auto push = [&](const int u, const int d) {
			if (dist[u] > d) {
				dist[u] = d;
				que.push(u);
			}
		};

		push(src, 0);
		while (!que.empty()) {
			const int u = que.front();
			que.pop();
			if (grid[u] != '.' and grid[u] != '#') {
				graph[id[grid[src]]][id[grid[u]]] = dist[u];
			}
			if (grid[u] != '.' and u != src) {
				continue;
			}

			if (u / W != 0) push(u - W, dist[u] + 1);
			if (u / W != H - 1) push(u + W, dist[u] + 1);
			if (u % W != 0) push(u - 1, dist[u] + 1);
			if (u % W != W - 1) push(u + 1, dist[u] + 1);
		}
	}

	vector dp(10, vector(1 << 10, pair(inf, inf)));
	dp[0][0] = {0, 0};
	for (int set = 0; set < (1 << 10); ++set) {
		for (int last = 0; last < 10; ++last) {
			const int src = (set == 0 ? id['S'] : id['0' + last]);
			vector<int> dist(V, inf);
			vector<char> ok(V, true), done(V);
			for (int i = 0; i < 10; ++i) {
				if (set >> i & 1) {
					ok[id['A' + i]] = false;
				} else {
					ok[id['a' + i]] = false;
				}
			}
			dist[src] = 0;
			while (true) {
				int select = -1;
				for (int i = 0; i < V; ++i) {
					if (!done[i] and dist[i] != inf and (select == -1 or dist[select] > dist[i])) {
						select = i;
					}
				}
				if (select == -1) break;
				done[select] = true;
				for (int next = 0; next < V; ++next) {
					if (!ok[next]) continue;
					dist[next] = min(dist[next], dist[select] + graph[select][next]);
				}
			}
			const auto& [x, y] = dp[last][set];
			for (int add = 0; add < 10; ++add) {
				if (!(set >> add & 1)) {
					dp[add][set | (1 << add)] = min(dp[add][set | (1 << add)], pair(x + dist[id['0' + add]], y - (set == 0 ? 0 : score[last][add])));
				}
			}
		}
	}

	pair ans(inf, inf);
	{
		const int src = id['T'];
		vector<int> dist(V, inf);
		vector<char> ok(V, true), done(V);
		for (int i = 0; i < 10; ++i) {
			ok[id['A' + i]] = false;
		}
		dist[src] = 0;
		while (true) {
			int select = -1;
			for (int i = 0; i < V; ++i) {
				if (!done[i] and dist[i] != inf and (select == -1 or dist[select] > dist[i])) {
					select = i;
				}
			}
			if (select == -1) break;
			done[select] = true;
			for (int next = 0; next < V; ++next) {
				if (!ok[next]) continue;
				dist[next] = min(dist[next], dist[select] + graph[select][next]);
			}
		}
		for (int i = 0; i < 10; ++i) {
			const auto& [x, y] = dp[i][(1 << 10) - 1];
			ans = min(ans, pair(x + dist[id['0' + i]], y));
		}
	}
	if (ans.first == inf) {
		cout << "-1\n";
	} else {
		cout << ans.first << ' ' << -ans.second << '\n';	
	}
	// dp[1024][10]
	// transition : 10240 times
	// dijkstra : 32 * 32
	// should not use std::map?

	return 0;
}
accuracy: 1
time_ms: 250
memory_kb: 8008
final_rank: 1

code_snippet: /* -*- coding: utf-8 -*-
 *
 * 0400.cc:  Maze &amp; Items
 */

#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#include<utility>
 
using namespace std;

/* constant */

const int N = 32;
const int BN = 10;
const int BBITS = 1 << BN;
const int BMSK = BBITS - 1;
const int MAX_W = 1000;
const int MAX_H = 1000;
const int MAX_HW = MAX_H * MAX_W;
const int INF = 1 << 30;

const int dys[] = { 0, -1, 0, 1 }, dxs[] = { 1, 0, -1, 0 };
const char vcs[] = "0123456789ABCDEFGHIJabcdefghijST";

/* typedef */

typedef queue<int> qi;
typedef pair<int,int> pii;
typedef vector<pii> vpii;

struct Dist {
  int d, x;
  Dist() {}
  Dist(int _d, int _x): d(_d), x(_x) {}
  bool operator<(const Dist &t) const {
    return d < t.d || (d == t.d && x > t.x);
  }
  bool operator>(const Dist &t) const {
    return d > t.d || (d == t.d && x < t.x);
  }
  bool operator==(const Dist &t) const { return d == t.d && x == t.x; }
  bool operator!=(const Dist &t) const { return ! (*this == t); }
};

struct Stat {
  int i, l, bs;
  Stat() {}
  Stat(int _i, int _l, int _bs): i(_i), l(_l), bs(_bs) {}
  bool operator<(const Stat &s) const { return i < s.i; }
  bool operator>(const Stat &s) const { return i > s.i; }
};

typedef pair<Dist,Stat> pds;

/* global variables */

char cmap[128], fs[MAX_H][MAX_W + 4];
int vps[N], ds[MAX_HW], ss[BN][BN];
vpii nbrs[N];
Dist dts[N][BN + 1][BBITS];

/* subroutines */

void bfs(int h, int w, int sc) {
  int st = vps[sc];
  if (st < 0) return;

  int hw = h * w;
  fill(ds, ds + hw, -1);
  ds[st] = 0;
  qi q;
  q.push(st);

  while (! q.empty()) {
    int u = q.front(); q.pop();
    int uy = u / w, ux = u % w;

    for (int di = 0; di < 4; di++) {
      int vy = uy + dys[di], vx = ux + dxs[di], v = vy * w + vx;
      if (vy >= 0 && vy < h && vx >= 0 && vx < w &&
	  fs[vy][vx] != '#' && ds[v] < 0) {
	ds[v] = ds[u] + 1;
	if (fs[vy][vx] == '.') q.push(v);
      }
    }
  }
}

/* main */

int main() {
  //freopen("input.txt", "r", stdin);
  //freopen("output.txt", "w", stdout);

  fill(cmap, cmap + 128, -1);
  for (int i = 0; i < N; i++) cmap[vcs[i]] = i;

  int w, h;
  scanf("%d%d", &w, &h);
  int hw = h * w;

  fill(vps, vps + N, -1);
  for (int y = 0, p = 0; y < h; y++) {
    scanf("%s", fs[y]);
    for (int x = 0; x < w; x++, p++) {
      int ci = cmap[fs[y][x]];
      if (ci >= 0) vps[ci] = p;
    }
  }

  for (int i = 0; i < BN; i++)
    for (int j = 0; j < BN; j++) scanf("%d", ss[i] + j);

  for (int sc = 0; sc < N; sc++)
    if (vps[sc] >= 0) {
      bfs(h, w, sc);
      for (int i = 0; i < N; i++) {
	int v = vps[i];
	if (v >= 0 && ds[v] > 0) {
	  nbrs[sc].push_back(pii(i, ds[v]));
	  //printf("%d->%d: %d\n", sc, i, ds[v]);
	}
      }
    }

  int st = N - 2, gl = N - 1;
  
  for (int i = 0; i < N; i++)
    for (int j = 0; j <= BN; j++)
      fill(dts[i][j], dts[i][j] + BBITS, Dist(INF, 0));
  dts[st][BN][0] = Dist(0, 0);

  priority_queue<pds,vector<pds>,greater<pds> > q;
  q.push(pds(Dist(0, 0), Stat(st, BN, 0)));

  Dist mind(-1, 0);
  while (! q.empty()) {
    pds ue = q.top(); q.pop();
    Dist ud = ue.first;
    Stat u = ue.second;
    if (dts[u.i][u.l][u.bs] != ud) continue;

    if (u.i == gl && u.bs == BMSK) {
      mind = ud;
      break;
    }

    for (auto vw: nbrs[u.i]) {
      int vi = vw.first, w = vw.second;
      Dist vd = Dist(ud.d + w, ud.x);
      if (dts[vi][u.l][u.bs] > vd) {
	if ((BN <= vi && vi < BN * 2 && (u.bs & (1 << (vi - BN)))) ||
	    (BN * 2 <= vi && vi < BN * 3 && ! (u.bs & (1 << (vi - BN * 2)))))
	  continue;
	dts[vi][u.l][u.bs] = vd;
	q.push(pds(vd, Stat(vi, u.l, u.bs)));
      }
    }

    if (u.i < BN && ! (u.bs & (1 << u.i))) {
      int vbs = u.bs | (1 << u.i);
      Dist vd = Dist(ud.d, ud.x + (u.l < BN ? ss[u.l][u.i] : 0));
      if (dts[u.i][u.i][vbs] > vd) {
	dts[u.i][u.i][vbs] = vd;
	q.push(pds(vd, Stat(u.i, u.i, vbs)));
      }
    }
  }

  if (mind.d < 0) puts("-1");
  else printf("%d %d\n", mind.d, mind.x);
  return 0;
}
accuracy: 1
time_ms: 350
memory_kb: 10892
final_rank: 3

code_snippet: #ifdef LOGX
#define _GLIBCXX_DEBUG
#endif
#include<bits/stdc++.h>
using namespace std;

using ll=long long;
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep2(i,s,n) for(int i=int(s);i<(int)(n);i++)
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define vv vector
const int big=1e9+7;
//const int big=998244353;
const char newl='\n';
const int inf=1e9+10;
const ll INF=ll(1e18)+10;
const int dx[]={1,0,-1,0};
const int dy[]={0,1,0,-1};

template<typename T>
T exp(T x,ll y,const T e){
    T res=e;
    while(y){
        if(y&1)res=res*x;
        x=x*x;
        y>>=1;
    }
    return res;
}

int lcm(int a,int b){
    return a/__gcd(a,b)*b;
}

struct mint{
    ll x;
    mint(ll xx=0):x(xx){
        x%=big;
        if(x<0)x+=big;
    }
    mint& operator+=(mint r){
        x+=r.x;
        if(x>=big)x-=big;
        return *this;
    }
    mint& operator*=(mint r){
        x*=r.x;
        x%=big;
        return *this;
    }
    friend mint operator+(mint l,mint r){
        l+=r;
        return l;
    }
    friend mint operator*(mint l,mint r){
        return l*=r;
    }
    friend ostream& operator<<(ostream &os,const mint &r){
        os << r.x;
        return os;
    }
};

vector<int> pfacs(int v){
    vector<int> res;
    for(int i=2;i*i<=v;i++){
        if(v%i==0){
            res.emplace_back(i);
            while(v%i==0)v/=i;
        }
    }
    if(v!=1)res.emplace_back(v);
    return res;
}

bool is_need(char c){
    return !(c=='.' || c=='#');
}
template<typename T>
bool chmin(T &a,T b){
    if(a<=b)return false;
    return a=b,true;
}

#define mybit(i,j) (((i)>>(j))&1)

int main(){
    //std::ios::sync_with_stdio(false);
    //std::cin.tie(nullptr);
    std::cout.precision(10);
/*------------------------------------*/
    auto  encode=[](char c){
        if('0'<=c && c<='9'){
            return c-'0';
        }
        else if(isupper(c)){
            if(c<='J')return 10+c-'A';
            else return 30+(c=='T');
        }
        else{
            return 20+c-'a';
        }
    };
    auto decode=[](int x)->char{
        if(x<=9)return '0'+x;
        else if(x<=19)return 'A'+x-10;
        else if(x<=29)return 'a'+x-20;
        return (x==30 ? 'S':'T');
    };
/////////////////////////////////////////////
    int h,w;
    cin >> w >> h;
    vector<string> grid(h);
    rep(i,h)cin >> grid[i];
    vector<vector<int>> score(10,vector<int>(10));
    rep(i,10)rep(j,10)cin >> score[i][j],score[i][j]*=-1;

    auto is_valid=[&](int i,int j){
        return 0<=i && i<h && 0<=j && j<w;
    };
    
    const int sz=32;
    vector<vector<int>> dist(sz,vector<int>(sz,inf));
    vector<pair<int,int>> needs;
    rep(i,h)rep(j,w)if(is_need(grid[i][j])){
        needs.emplace_back(i,j);
    }
    sort(all(needs),[&](pair<int,int> l,pair<int,int> r){
        return encode(grid[l.first][l.second])<encode(grid[r.first][r.second]);
    });
    for(auto p:needs){
        int s=p.first,t=p.second;
        vector<vector<int>> cost(h,vector<int>(w,inf));
        cost[s][t]=0;
        queue<pair<int,int>> q;
        q.emplace(s,t);
        while(!q.empty()){
            auto P=q.front();q.pop();
            int i=P.first,j=P.second;
            rep(k,4){
                int ni=i+dx[k],nj=j+dy[k];
                if(!is_valid(ni,nj))continue;
                if(chmin(cost[ni][nj],cost[i][j]+1) && grid[ni][nj]=='.'){
                    q.emplace(ni,nj);
                }
            }
        }
        for(auto xy:needs){
            int x=xy.first,y=xy.second;
            dist[encode(grid[s][t])][encode(grid[x][y])]=cost[x][y];
        }
    }

    vector<vector<pair<int,int>>> dp(1<<10,vector<pair<int,int>>(10,{inf,inf}));
    {
        vector<int> cost(32,inf);
        cost[encode('S')]=0;
        using P=pair<int,int>;
        priority_queue<P,vector<P>,greater<P>> q;
        q.emplace(0,encode('S'));
        while(!q.empty()){
            int d=q.top().first;
            int x=q.top().second;
            q.pop();
            if(cost[x]!=d)continue;
            rep(y,32){
                bool can=true;
                char c=decode(y);
                if('A'<=c && c<='J'){
                    can&=!mybit(0,c-'A');
                }
                if('a'<=c && c<='j'){
                    can&=mybit(0,c-'a');
                }
                if(can && chmin(cost[y],cost[x]+dist[x][y])){
                    q.emplace(cost[y],y);
                }
            }
        }
        for(char c='0';c<='9';c++){
            dp[1<<(c-'0')][c-'0']={cost[encode(c)],0};
        }
    }
    pair<int,int> ans={inf,inf};
    rep2(S,1,1<<10)rep(i,10){
        vector<int> cost(32,inf);
        cost[encode('0'+i)]=0;
        using P=pair<int,int>;
        priority_queue<P,vector<P>,greater<P>> q;
        q.emplace(0,encode('0'+i));
        while(!q.empty()){
            ll d=q.top().first;
            int x=q.top().second;
            q.pop();
            if(cost[x]!=d)continue;
            rep(y,32){
                bool can=true;
                char c=decode(y);
                if('A'<=c && c<='J'){
                    can&=!mybit(S,c-'A');
                }
                if('a'<=c && c<='j'){
                    can&=mybit(S,c-'a');
                }
                if(can && chmin(cost[y],cost[x]+dist[x][y])){
                    q.emplace(cost[y],y);
                }
            }
        }
        //あとはTに戻るだけ
        if(S==(1<<10)-1){
            int di=dp[S][i].first, sc=dp[S][i].second;
            chmin(ans,{di+cost[encode('T')],sc});
        }
        else rep(j,10)if(!mybit(S,j)){
            int di=dp[S][i].first, sc=dp[S][i].second;
            chmin(dp[S | (1<<j)][j],{di+cost[j],sc+score[i][j]});
        }
    }
    if(ans.first==(int)inf)cout << -1 << newl;
    else cout << ans.first << ' ' << -ans.second << newl;
}
//dp[S][i]=Sに行ってiが最後
//スコアは-1倍で保持する->最小化
accuracy: 1
time_ms: 330
memory_kb: 8872
final_rank: 2

code_snippet: #include<iostream>
#include<queue>
#include<vector>
using namespace std;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
int H,W;
string S[1000];
int invS[1000][1000];
vector<pair<int,int> >A;
int dist[200][200];
int chr[200];
int id[12];
int calc[1000][1000];
pair<int,int>dp[1<<10][10];
int s[10][10];
int D[200];
main()
{
	cin>>W>>H;
	for(int i=0;i<H;i++)cin>>S[i];
	for(int i=0;i<10;i++)for(int j=0;j<10;j++)cin>>s[i][j];
	for(int i=0;i<H;i++)for(int j=0;j<W;j++)
	{
		if(S[i][j]=='S')
		{
			id[10]=A.size();
			A.push_back(make_pair(i,j));
		}
		else if(S[i][j]=='T')
		{
			id[11]=A.size();
			A.push_back(make_pair(i,j));
		}
		else if(S[i][j]>='0'&&S[i][j]<='9')
		{
			id[S[i][j]-'0']=A.size();
			A.push_back(make_pair(i,j));
		}
		else if(S[i][j]>='A'&&S[i][j]<='J')
		{
			chr[A.size()]=S[i][j]-'A'+1;
			A.push_back(make_pair(i,j));
		}
		else if(S[i][j]>='a'&&S[i][j]<='j')
		{
			chr[A.size()]=-(S[i][j]-'a'+1);
			A.push_back(make_pair(i,j));
		}
		else if(S[i][j]=='.')
		{
			bool f=false;
			for(int r=0;r<4;r++)
			{
				int x=i+dx[r],y=j+dy[r];
				if(x<0||y<0||x>=H||y>=W)continue;
				if(S[x][y]>='A'&&S[x][y]<='J'||S[x][y]>='a'&&S[x][y]<='j')f=true;
			}
			if(f)A.push_back(make_pair(i,j));
		}
	}
	int n=A.size();
	for(int i=0;i<n;i++)invS[A[i].first][A[i].second]=i+1;
	for(int i=0;i<n;i++)for(int j=0;j<n;j++)dist[i][j]=i==j?0:1e9;
	for(int i=0;i<n;i++)
	{
		int sx=A[i].first,sy=A[i].second;
		if(chr[i]!=0)
		{
			for(int r=0;r<4;r++)
			{
				int x=sx+dx[r],y=sy+dy[r];
				if(x<0||y<0||x>=H||y>=W)continue;
				if(invS[x][y]>0)dist[i][invS[x][y]-1]=1;
			}
			continue;
		}
		for(int i=0;i<H;i++)for(int j=0;j<W;j++)calc[i][j]=1e9;
		calc[sx][sy]=0;
		queue<pair<int,int> >P;
		P.push(make_pair(sx,sy));
		while(!P.empty())
		{
			int x=P.front().first,y=P.front().second;
			P.pop();
			if(S[x][y]>='A'&&S[x][y]<='J'||S[x][y]>='a'&&S[x][y]<='j')continue;
			for(int r=0;r<4;r++)
			{
				int tx=x+dx[r],ty=y+dy[r];
				if(tx<0||ty<0||tx>=H||ty>=W||S[tx][ty]=='#'||calc[tx][ty]<=calc[x][y]+1)continue;
				calc[tx][ty]=calc[x][y]+1;
				P.push(make_pair(tx,ty));
			}
		}
		for(int j=0;j<n;j++)
		{
			dist[i][j]=calc[A[j].first][A[j].second];
		}
	}
	pair<int,int>ans=make_pair(1e9,-1);
	for(int i=0;i<1<<10;i++)for(int j=0;j<10;j++)dp[i][j]=make_pair(1e9,-1);
	dp[0][0]=make_pair(0,0);
	for(int i=0;i<1<<10;i++)for(int j=0;j<10;j++)if(dp[i][j].second>=0)
	{
		int st=id[j];
		if(i==0)st=id[10];
		for(int k=0;k<n;k++)D[k]=1e9;
		priority_queue<pair<int,int> >P;
		P.push(make_pair(0,st));
		D[st]=0;
		while(!P.empty())
		{
			int cost=-P.top().first,u=P.top().second;
			P.pop();
			if(D[u]<cost)continue;
			if(chr[u]>0)
			{
				if(i>>chr[u]-1&1)continue;
			}
			else if(chr[u]<0)
			{
				if(!(i>>-chr[u]-1&1))continue;
			}
			for(int v=0;v<n;v++)
			{
				int nxt=cost+dist[u][v];
				if(D[v]>nxt)
				{
					D[v]=nxt;
					P.push(make_pair(-nxt,v));
				}
			}
		}
		if(i+1<1<<10)
		{
			for(int k=0;k<10;k++)if(!(i>>k&1)&&D[id[k]]<(int)1e9)
			{
				pair<int,int>nxt=make_pair(dp[i][j].first+D[id[k]],dp[i][j].second);
				if(i!=0)nxt.second+=s[j][k];
				pair<int,int>now=dp[i|1<<k][k];
				if(now.first>nxt.first||now.first==nxt.first&&now.second<nxt.second)
				{
					dp[i|1<<k][k]=nxt;
				}
			}
		}
		else
		{
			if(D[id[11]]<(int)1e9)
			{
				pair<int,int>nxt=make_pair(dp[i][j].first+D[id[11]],dp[i][j].second);
				if(ans.first>nxt.first||ans.first==nxt.first&&ans.second<nxt.second)ans=nxt;
			}
		}
	}
	if(ans.second<0)cout<<-1<<endl;
	else cout<<ans.first<<" "<<ans.second<<endl;
}
accuracy: 1
time_ms: 970
memory_kb: 8112
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
#define rep(i,n) for(int i=0; i<(n); i++)

struct Pos { int x, y; };
Pos operator+(Pos l, Pos r) { return { l.x + r.x,l.y + r.y }; }
bool operator==(Pos l, Pos r) { return l.x == r.x && l.y == r.y; }

struct QueueNode { int d, score, itemmask, pos, lastitem; };
bool operator<(QueueNode l, QueueNode r) {
	if(l.d != r.d) return l.d > r.d;
	return l.score < r.score;
}


static const string SpMass = "0123456789abcdefghijABCDEFGHIJST";

int H, W;
int G[1000][1000];
Pos P[32];
int Score[11][11];

static const Pos dx[4] = { {-1,0},{1,0},{0,-1},{0,1} };

int DG[1000][1000];
int D[32][32];

pair<int, int> D2[1 << 10][32][11];

int& at_G(Pos p) { return G[p.x][p.y]; }
int& at_DG(Pos p) { return DG[p.x][p.y]; }
bool onBoard(Pos p) {
	if (p.x < 0 || W <= p.x) return false;
	if (p.y < 0 || H <= p.y) return false;
	return true;
}

int main() {
	rep(i, 32) P[i] = { -1,-1 };

	cin >> W >> H;
	rep(y, H) rep(x, W) {
		char c; cin >> c;
		if (c == '.') { G[x][y] = 1; }
		else if (c == '#') { G[x][y] = 0; }
		else {
			int massTy = SpMass.find(c);
			G[x][y] = -1;
			P[massTy] = { x,y };
		}
	}
	rep(i, 11) rep(j, 11) Score[i][j] = 0;
	rep(i, 10) rep(j, 10) cin >> Score[i][j];

	rep(i, 32) rep(j, 32) D[i][j] = -1;

	rep(s, 32) {
		if (!onBoard(P[s])) continue;
		rep(x, W) rep(y, H) DG[x][y] = -1;

		queue<Pos> Q;
		Q.push(P[s]);
		at_DG(P[s]) = 0;

		while (Q.size()) {
			Pos p = Q.front(); Q.pop();
			if (at_G(p) == -1 && !(p == P[s])) continue;
			rep(dxi, 4) {
				Pos nx = p + dx[dxi];
				if (at_DG(nx) != -1) continue;
				if (!onBoard(nx)) continue;
				if (at_G(nx) == 0) continue;
				at_DG(nx) = at_DG(p) + 1;
				Q.push(nx);
			}
		}

		rep(t, 32) if (onBoard(P[t])) D[s][t] = at_DG(P[t]);
	}

	rep(i, 1 << 10) rep(j, 32) rep(k, 11) D2[i][j][k] = { -1, -1 };
	{
		priority_queue<QueueNode> Q;
		Q.push({ 0,0,0,30,10 });
		while (Q.size()) {
			QueueNode q = Q.top(); Q.pop();
			if (D2[q.itemmask][q.pos][q.lastitem].first != -1) continue;
			D2[q.itemmask][q.pos][q.lastitem] = { q.d, q.score };

			if (0 <= q.pos && q.pos < 10) if(0 == (q.itemmask & (1 << q.pos)))
				Q.push({ q.d, q.score + Score[q.lastitem][q.pos], q.itemmask | (1 << q.pos), q.pos, q.pos });

			rep(to, 32) {
				if (10 <= to && to < 20) if (0 == ((1 << (to - 10)) & q.itemmask)) continue;
				if (20 <= to && to < 30) if (0 != ((1 << (to - 20)) & q.itemmask)) continue;
				if (D[q.pos][to] == -1) continue;
				Q.push({ q.d + D[q.pos][to], q.score, q.itemmask, to, q.lastitem });
			}
		}
	}

	int ans_d = 10000000, ans_score = -1;
	rep(i, 10) {
		if (D2[(1 << 10) - 1][31][i].first == -1) continue;
		bool ok = false;
		if (ans_d > D2[(1 << 10) - 1][31][i].first) ok = true;
		if (ans_d == D2[(1 << 10) - 1][31][i].first) if (ans_score < D2[(1 << 10) - 1][31][i].second) ok = true;
		if (ok) {
			ans_d = D2[(1 << 10) - 1][31][i].first;
			ans_score = D2[(1 << 10) - 1][31][i].second;
		}
	}

	if (ans_score == -1) { cout << -1 << endl; }
	else cout << ans_d << " " << ans_score << endl;

	return 0;
}
accuracy: 0.29545454545454547
time_ms: 510
memory_kb: 26568
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
#define rep(i,n) for(int i=0; i<(n); i++)

struct Pos { int x, y; };
Pos operator+(Pos l, Pos r) { return { l.x + r.x,l.y + r.y }; }
bool operator==(Pos l, Pos r) { return l.x == r.x && l.y == r.y; }

struct QueueNode { int d, score, itemmask, pos, lastitem; };
bool operator<(QueueNode l, QueueNode r) {
	if(l.d != r.d) return l.d > r.d;
	return l.score < r.score;
}


static const string SpMass = "0123456789abcdefghijABCDEFGHIJST";

int H, W;
int G[1000][1000];
Pos P[32];
int Score[11][11];

static const Pos dx[4] = { {-1,0},{1,0},{0,-1},{0,1} };

int DG[1000][1000];
int D[32][32];

pair<int, int> D2[1 << 10][32][11];

int& at_G(Pos p) { return G[p.x][p.y]; }
int& at_DG(Pos p) { return DG[p.x][p.y]; }
bool onBoard(Pos p) {
	if (p.x < 0 || W <= p.x) return false;
	if (p.y < 0 || H <= p.y) return false;
	return true;
}

int main() {
	rep(i, 32) P[i] = { -1,-1 };

	cin >> W >> H;
	rep(y, H) rep(x, W) {
		char c; cin >> c;
		if (c == '.') { G[x][y] = 1; }
		else if (c == '#') { G[x][y] = 0; }
		else {
			int massTy = SpMass.find(c);
			G[x][y] = -1;
			P[massTy] = { x,y };
		}
	}
	rep(i, 11) rep(j, 11) Score[i][j] = 0;
	rep(i, 10) rep(j, 10) cin >> Score[i][j];

	rep(i, 32) rep(j, 32) D[i][j] = -1;

	rep(s, 32) {
		if (!onBoard(P[s])) continue;
		rep(x, W) rep(y, H) DG[x][y] = -1;

		queue<Pos> Q;
		Q.push(P[s]);
		at_DG(P[s]) = 0;

		while (Q.size()) {
			Pos p = Q.front(); Q.pop();
			if (at_G(p) == -1 && !(p == P[s])) continue;
			rep(dxi, 4) {
				Pos nx = p + dx[dxi];
				if (at_DG(nx) != -1) continue;
				if (!onBoard(nx)) continue;
				if (at_G(nx) == 0) continue;
				at_DG(nx) = at_DG(p) + 1;
				Q.push(nx);
			}
		}

		rep(t, 32) if (onBoard(P[t])) D[s][t] = at_DG(P[t]);
	}

	rep(i, 1 << 10) rep(j, 32) rep(k, 11) D2[i][j][k] = { -1, -1 };
	{
		priority_queue<QueueNode> Q;
		Q.push({ 0,0,0,30,10 });
		while (Q.size()) {
			QueueNode q = Q.top(); Q.pop();
			if (D2[q.itemmask][q.pos][q.lastitem].first != -1) continue;
			D2[q.itemmask][q.pos][q.lastitem] = { q.d, q.score };

			if (0 <= q.pos && q.pos < 10)
				Q.push({ q.d, q.score + Score[q.lastitem][q.pos], q.itemmask | (1 << q.pos), q.pos, q.pos });

			rep(to, 32) {
				if (10 <= to && to < 20) if (0 == ((1 << (to - 10)) & q.itemmask)) continue;
				if (20 <= to && to < 30) if (0 != ((1 << (to - 20)) & q.itemmask)) continue;
				if (D[q.pos][to] == -1) continue;
				Q.push({ q.d + D[q.pos][to], q.score, q.itemmask, to, q.lastitem });
			}
		}
	}

	int ans_d = 10000000, ans_score = -1;
	rep(i, 10) {
		if (D2[(1 << 10) - 1][31][i].first == -1) continue;
		bool ok = false;
		if (ans_d > D2[(1 << 10) - 1][31][i].first) ok = true;
		if (ans_d == D2[(1 << 10) - 1][31][i].first) if (ans_score < D2[(1 << 10) - 1][31][i].second) ok = true;
		if (ok) {
			ans_d = D2[(1 << 10) - 1][31][i].first;
			ans_score = D2[(1 << 10) - 1][31][i].second;
		}
	}

	if (ans_score == -1) { cout << -1 << endl; }
	else cout << ans_d << " " << ans_score << endl;

	return 0;
}
accuracy: 0.09090909090909091
time_ms: 130
memory_kb: 16180
final_rank: 20

code_snippet: #include<bits/stdc++.h>
#define newl endl
#define all(vec) vec.begin(),vec.end()
using namespace std;
template<class T>
using V=vector<T>;
using ll=long long;
const ll INF=1LL<<30;
const ll mod=1e9+7;
using P=pair<int,int>;
int dy[4]={0,1,0,-1},dx[4]={1,0,-1,0};
bool chmin(P& a,P b){if(a>b){a=b;return true;}return false;}
void ok(){cout<<"ok"<<newl;}
int main(){
    int w,h;cin>>w>>h;
    V<string> c(h);
    V<int> y(32,-1),x(32,-1);
    for(int i=0;i<h;i++){
        cin>>c[i];
        for(int j=0;j<w;j++){
            if(c[i][j]=='S'){
                y[30]=i,x[30]=j;
            }else if(c[i][j]=='T'){
                y[31]=i,x[31]=j;
            }else if(0<=c[i][j]-'0'&&c[i][j]-'0'<=9){
                y[c[i][j]-'0']=i,x[c[i][j]-'0']=j;
            }else if(0<=c[i][j]-'a'&&c[i][j]-'a'<=9){
                y[20+c[i][j]-'a']=i,x[20+c[i][j]-'a']=j;
            }else if(isupper(c[i][j])){
                y[10+c[i][j]-'A']=i,x[10+c[i][j]-'A']=j;
            }
        }
    }
    V<V<int>> d(32,V<int>(32,INF)),ds(h,V<int>(w));
    for(int i=0;i<32;i++){
        if(y[i]<0)continue;
        for(int j=0;j<h;j++)for(int k=0;k<w;k++)ds[j][k]=INF;
        ds[y[i]][x[i]]=0;
        queue<P> q;
        q.emplace(y[i],x[i]);
        while(!q.empty()){
            int yy=q.front().first,xx=q.front().second;
            q.pop();
            if(c[yy][xx]!='.'&&c[yy][xx]!=c[y[i]][x[i]]){
                 if(c[yy][xx]=='S'){
                    d[i][30]=ds[yy][xx];
                }else if(c[yy][xx]=='T'){
                    d[i][31]=ds[yy][xx];
                }else if(0<=c[yy][xx]-'0'&&c[yy][xx]-'0'<=9){
                    d[i][c[yy][xx]-'0']=ds[yy][xx];
                }else if(islower(c[yy][xx])){
                    d[i][20+c[yy][xx]-'a']=ds[yy][xx];
                }else if(isupper(c[yy][xx])){
                    d[i][10+c[yy][xx]-'A']=ds[yy][xx];
                }
                continue;
            }
            for(int j=0;j<4;j++){
                int ny=yy+dy[j],nx=xx+dx[j];
                if(ny<0||nx<0||ny>=h||nx>=w)continue;
                if(c[ny][nx]=='#'||ds[ny][nx]!=INF)continue;
                ds[ny][nx]=ds[yy][xx]+1;
                q.emplace(ny,nx);
            }
        }
    }
    V<V<int>> s(11,V<int>(11,INF));
    for(int i=0;i<10;i++){
        for(int j=0;j<10;j++){
            cin>>s[i][j];
        }
    }
    V<V<V<P>>> dp(32,V<V<P>>(1<<10,V<P>(10,P(INF,0))));
    priority_queue<pair<P,int>,V<pair<P,int>>,greater<pair<P,int>>> que;
    dp[30][0][0]=P(0,0);
    que.emplace(P(0,0),30*(1<<10)*10);
    while(!que.empty()){
        int dd=que.top().first.first,id=que.top().second,sc=que.top().first.second;
        que.pop();
        int i=id/((1<<10)*10);
        int j=(id-i*((1<<10)*10))/10;
        int k=id%10;
        if(dd>dp[i][j][k].first)continue;
        for(int l=0;l<32;l++){
            if(l==i||d[i][l]==INF)continue;
            int ts=sc;
            if(j>0&&l<=9)ts=sc-s[k][l];
            if(l<=9){
                if(!((j>>l)&1)){
                    if(chmin(dp[l][j|(1<<l)][l],P(dd+d[i][l],ts)))que.emplace(make_pair(dp[l][j|(1<<l)][l],l*(1<<10)*10+(j|(1<<l))*10+l));
                }
                if(chmin(dp[l][j][k],P(dd+d[i][l],sc)))que.emplace(make_pair(dp[l][j][k],l*(1<<10)*10+j*10+k));
            }else if(l<=19){
                if((j>>(l-10))&1)continue;
                if(chmin(dp[l][j][k],P(dd+d[i][l],ts)))que.emplace(make_pair(dp[l][j][k],l*(1<<10)*10+j*10+k));
            }else if(l<=29){
                if(!((j>>(l-20))&1))continue;
                if(chmin(dp[l][j][k],P(dd+d[i][l],ts)))que.emplace(make_pair(dp[l][j][k],l*(1<<10)*10+j*10+k));
            }else{
                if(chmin(dp[l][j][k],P(dd+d[i][l],ts)))que.emplace(make_pair(dp[l][j][k],l*(1<<10)*10+j*10+k));
            }
        }
    }
    P res=P(INF,0);
    for(int i=0;i<10;i++){
        res=min(res,dp[31][(1<<10)-1][i]);
    }
    if(res.first==INF){
        cout<<-1<<newl;
        return 0;
    }
    cout<<res.first<<" "<<-res.second<<newl;
}
accuracy: 1
time_ms: 470
memory_kb: 11836
final_rank: 6

code_snippet: #include<bits/stdc++.h>
#define newl endl
#define all(vec) vec.begin(),vec.end()
using namespace std;
template<class T>
using V=vector<T>;
using ll=long long;
const ll INF=1LL<<30;
const ll mod=1e9+7;
using P=pair<int,int>;
int dy[4]={0,1,0,-1},dx[4]={1,0,-1,0};
bool chmin(P& a,P b){if(a>b){a=b;return true;}return false;}
void ok(){cout<<"ok"<<newl;}
int main(){
    int w,h;cin>>w>>h;
    V<string> c(h);
    V<int> y(32,-1),x(32,-1);
    for(int i=0;i<h;i++){
        cin>>c[i];
        for(int j=0;j<w;j++){
            if(c[i][j]=='S'){
                y[30]=i,x[30]=j;
            }else if(c[i][j]=='T'){
                y[31]=i,x[31]=j;
            }else if(0<=c[i][j]-'0'&&c[i][j]-'0'<=9){
                y[c[i][j]-'0']=i,x[c[i][j]-'0']=j;
            }else if(0<=c[i][j]-'a'&&c[i][j]-'a'<=9){
                y[20+c[i][j]-'a']=i,x[20+c[i][j]-'a']=j;
            }else if(isupper(c[i][j])){
                y[10+c[i][j]-'A']=i,x[10+c[i][j]-'A']=j;
            }
        }
    }
    V<V<int>> d(32,V<int>(32,INF)),ds(h,V<int>(w));
    for(int i=0;i<32;i++){
        if(y[i]<0)continue;
        for(int j=0;j<h;j++)for(int k=0;k<w;k++)ds[j][k]=INF;
        ds[y[i]][x[i]]=0;
        queue<P> q;
        q.emplace(y[i],x[i]);
        while(!q.empty()){
            int yy=q.front().first,xx=q.front().second;
            q.pop();
            if(c[yy][xx]!='.'&&c[yy][xx]!=c[y[i]][x[i]]){
                 if(c[yy][xx]=='S'){
                    d[i][30]=ds[yy][xx];
                }else if(c[yy][xx]=='T'){
                    d[i][31]=ds[yy][xx];
                }else if(0<=c[yy][xx]-'0'&&c[yy][xx]-'0'<=9){
                    d[i][c[yy][xx]-'0']=ds[yy][xx];
                }else if(islower(c[yy][xx])){
                    d[i][20+c[yy][xx]-'a']=ds[yy][xx];
                }else if(isupper(c[yy][xx])){
                    d[i][10+c[yy][xx]-'A']=ds[yy][xx];
                }
                continue;
            }
            for(int j=0;j<4;j++){
                int ny=yy+dy[j],nx=xx+dx[j];
                if(ny<0||nx<0||ny>=h||nx>=w)continue;
                if(c[ny][nx]=='#'||ds[ny][nx]!=INF)continue;
                ds[ny][nx]=ds[yy][xx]+1;
                q.emplace(ny,nx);
            }
        }
    }
    V<V<int>> s(11,V<int>(11,INF));
    for(int i=0;i<10;i++){
        for(int j=0;j<10;j++){
            cin>>s[i][j];
        }
    }
    V<V<V<P>>> dp(32,V<V<P>>(1<<10,V<P>(10,P(INF,0))));
    priority_queue<pair<P,int>,V<pair<P,int>>,greater<pair<P,int>>> que;
    dp[30][0][0]=P(0,0);
    que.emplace(P(0,0),30*(1<<10)*10);
    while(!que.empty()){
        int dd=que.top().first.first,id=que.top().second,sc=que.top().first.second;
        que.pop();
        int i=id/((1<<10)*10);
        int j=(id-i*((1<<10)*10))/10;
        int k=id%10;
        if(dd>dp[i][j][k].first)continue;
        for(int l=0;l<32;l++){
            if(l==i)continue;
            int ts=sc;
            if(j>0&&l<=9)ts=sc-s[k][l];
            if(l<=9){
                if(chmin(dp[l][j|(1<<l)][l],P(dd+d[i][l],ts)))que.emplace(make_pair(dp[l][j|(1<<l)][l],l*(1<<10)*10+(j|(1<<l))*10+l));
            }else if(l<=19){
                if((j>>(l-10))&1)continue;
                if(chmin(dp[l][j][k],P(dd+d[i][l],ts)))que.emplace(make_pair(dp[l][j][k],l*(1<<10)*10+j*10+k));
            }else if(l<=29){
                if(!((j>>(l-20))&1))continue;
                if(chmin(dp[l][j][k],P(dd+d[i][l],ts)))que.emplace(make_pair(dp[l][j][k],l*(1<<10)*10+j*10+k));
            }else{
                if(chmin(dp[l][j][k],P(dd+d[i][l],ts)))que.emplace(make_pair(dp[l][j][k],l*(1<<10)*10+j*10+k));
            }
        }
    }
    P res=P(INF,0);
    for(int i=0;i<10;i++){
        res=min(res,dp[31][(1<<10)-1][i]);
    }
    if(res.first==INF){
        cout<<-1<<newl;
        return 0;
    }
    cout<<res.first<<" "<<-res.second<<newl;
}
accuracy: 0.09090909090909091
time_ms: 20
memory_kb: 7356
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
vector<int> dy = {1, 0, -1, 0};
vector<int> dx = {0, 1, 0, -1};
const int INF = 100000000;
int main(){
  int W, H;
  cin >> W >> H;
  vector<vector<char>> c(H + 2, vector<char>(W + 2, '#'));
  for (int i = 1; i <= H; i++){
    for (int j = 1; j <= W; j++){
      cin >> c[i][j];
    }
  }
  vector<vector<int>> s(10, vector<int>(10));
  for (int i = 0; i < 10; i++){
    for (int j = 0; j < 10; j++){
      cin >> s[i][j];
    }
  }
  vector<int> y, x;
  int V = y.size();
  for (int i = 1; i <= H; i++){
    for (int j = 1; j <= W; j++){
      if (c[i][j] != '#' && c[i][j] != '.'){
        y.push_back(i);
        x.push_back(j);
        V++;
      }
    }
  }
  vector<vector<int>> d(V, vector<int>(V, INF));
  for (int i = 0; i < V; i++){
    vector<vector<int>> d2(H + 2, vector<int>(W + 2, INF));
    d2[y[i]][x[i]] = 0;
    queue<pair<int, int>> Q;
    Q.push(make_pair(y[i], x[i]));
    while (!Q.empty()){
      int cy = Q.front().first;
      int cx = Q.front().second;
      Q.pop();
      for (int j = 0; j < 4; j++){
        int y2 = cy + dy[j];
        int x2 = cx + dx[j];
        if (c[y2][x2] != '#'){
          if (d2[y2][x2] == INF){
            d2[y2][x2] = d2[cy][cx] + 1;
            if (c[y2][x2] == '.'){
              Q.push(make_pair(y2, x2));
            }
          }          
        }
      }
    }
    for (int j = 0; j < V; j++){
      d[i][j] = d2[y[j]][x[j]];
    }
  }
  vector<int> id(12);
  vector<int> up(10, -1), lo(10, -1);
  for (int i = 0; i < V; i++){
    char ch = c[y[i]][x[i]];
    if (ch == 'S'){
      id[0] = i;
    }
    if (ch == 'T'){
      id[1] = i;
    }
    if ('0' <= ch && ch <= '9'){
      id[ch - '0' + 2] = i;
    }
    if ('A' <= ch && ch <= 'J'){
      up[ch - 'A'] = i;
    }
    if ('a' <= ch && ch <= 'j'){
      lo[ch - 'a'] = i;
    }
  }
  vector<vector<vector<int>>> d2(1024, vector<vector<int>>(12, vector<int>(12, INF)));
  for (int i = 0; i < 1024; i++){
    vector<bool> ok(V, true);
    for (int j = 0; j < 10; j++){
      if (i >> j & 1){
        if (up[j] != -1){
          ok[up[j]] = false;
        }
      } else {
        if (lo[j] != -1){
          ok[lo[j]] = false;
        }
      }
    }
    vector<vector<int>> E = d;
    for (int j = 0; j < V; j++){
      for (int k = 0; k < V; k++){
        if (!ok[j] || !ok[k]){
          E[j][k] = INF;
        }
      }
    }
    for (int j = 0; j < V; j++){
      for (int k = 0; k < V; k++){
        for (int l = 0; l < V; l++){
          E[k][l] = min(E[k][l], E[k][j] + E[j][l]);
        }
      }
    }
    for (int j = 0; j < 12; j++){
      for (int k = 0; k < 12; k++){
        d2[i][j][k] = E[id[j]][id[k]];
      }
    }
  }
  int ans1 = INF;
  int ans2 = 0;
  vector<int> p(10);
  for (int i = 0; i < 10; i++){
    p[i] = i;
  }
  for (int i = 0; i < 3628800; i++){
    long long dist = 0;
    int S = 0;
    dist += d2[0][0][p[0] + 2];
    int score = 0;
    for (int j = 0; j < 9; j++){
      S += 1 << p[j];
      score += s[p[j]][p[j + 1]];
      dist += d2[S][p[j] + 2][p[j + 1] + 2];
    }
    dist += d2[1023][p[9] + 2][1];
    if (dist < ans1){
      ans1 = dist;
      ans2 = score;
    } else if (dist == ans1){
      ans2 = max(ans2, score);
    }
    next_permutation(p.begin(), p.end());
  }
  if (ans1 == INF){
    cout << -1 << endl;
  } else {
    cout << ans1 << ' ' << ans2 << endl;
  }
}
accuracy: 1
time_ms: 440
memory_kb: 7864
final_rank: 4

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
 
#define REP(i, n) for (ll i = 0; i < n; i++)
#define REPR(i, n) for (ll i = n; i >= 0; i--)
#define FOR(i, m, n) for (ll i = m; i < n; i++)
#define FORR(i, m, n) for (ll i = m; i >= n; i--)
#define REPO(i, n) for (ll i = 1; i <= n; i++)
#define ll long long
#define INF (ll)1 << 60
#define MINF (-1   INF)
#define ALL(n) n.begin(), n.end()
#define MOD 1000000007
#define P pair<ll, ll>

ll v1[4] = {1, -1, 0, 0}, v2[4] = {0, 0, 1, -1};
#define PP pair<P, ll>
ll h, w, t[11][11], d[40][40], dp[1100][12][12], dp2[1100][12];
string s[1100];
unordered_map<char, int> mp;

void bfs(int x, int y, int num){//0~9, .の道
    vector<vector<bool>> used(h, vector<bool>(w));
    queue<PP> q;
    q.push(PP(P(x, y), 0));
    used[x][y] = true;
    while(!q.empty()){
        PP now = q.front();
        ll nx = now.first.first, ny = now.first.second, di = now.second;
        q.pop();
        ll nmp = mp[s[nx][ny]];
        if (nmp <= 31) d[num][nmp] = min(d[num][nmp], di);
        if (!(nmp == num) and ((nmp >= 10 and nmp <= 29) or nmp == 33)) continue;//!!!
        REP(i, 4){
            ll rx = nx + v1[i], ry = ny + v2[i];
            if (0 > rx or rx >= h or 0 > ry or ry >= w) continue;
            if (used[rx][ry]) continue;
            if (mp[s[rx][ry]] == 33) continue;
            used[rx][ry] = true;
            q.push(PP(P(rx, ry), di + 1));
        }
        //cout << nx << " " << ny << endl;
    }
   // cout << "!" << endl;
}

ll bfs2(ll b, ll x, ll y){
    if (x == 10) x = 30;
    if (y == 11) y = 31;
    vector<ll> ds(33, INF), ls;
    ds[x] = 0;
    REP(i, 10){
        if (b & (1 << i)) ls.push_back(20 + i);
        else ls.push_back(10 + i);
    }
    ls.push_back(y);
    priority_queue<P, vector<P>, greater<P>> q;
    
    q.push(P(0, x));
    while(!q.empty()){
        P now = q.top();
        q.pop();
        ll c = now.first, fr = now.second;
        if (c > ds[fr]) continue;
        REP(i, ls.size()){
            if(ds[fr] + d[fr][ls[i]] < ds[ls[i]]){
                ds[ls[i]] = ds[fr] + d[fr][ls[i]];
                q.push(P(ds[ls[i]], ls[i]));
            }
        }
    }
    return ds[y];
    
}

int main(){
    REP(i, 40){
        REP(j, 40){
            if (i != j) d[i][j] = INF;
        }
    }
    cin >> w >> h;
    REP(i, h){
        cin >> s[i];
    }
    REP(i, 10){
        REP(j, 10){
            cin >> t[i][j];
        }
    }
    REP(i, 10){
        mp['0' + i] = i;
        mp['A' + i] = 10 + i;
        mp['a' + i] = 20 + i;
    }
    mp['S'] = 30;
    mp['T'] = 31;
    mp['.'] = 32;
    mp['#'] = 33;
    //cout << "!" << endl;
    REP(i, h){
        REP(j, w){
            if (mp[s[i][j]] <= 31) bfs(i, j, mp[s[i][j]]);
        }
    }
   // cout << "!" << endl;
    REP(k, 1 << 10){
        REP(i, 10){
            REP(j, 10){
                if (i == j) continue;
                dp[k][i][j] = bfs2(k, i, j);
            }
        }
    }
    REP(i, 10){
        dp[0][10][i] = bfs2(0, 10, i);
        dp[(1 << 10) - 1][i][11] = bfs2((1 << 10) - 1, i, 11);
    }
    ll ans = INF, ans2 = 0;
    vector<int> v;
    v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    do{
        bool ok = true;
        ll n1 = 0, n2 = 0, nb = 0;
        if (dp[0][10][v[0]] == INF) ok = false;
        n1 += dp[0][10][v[0]];
        nb += (1 << v[0]);
        REP(i, 9){
            if (dp[nb][v[i]][v[i + 1]] == INF) ok = false;
            n1 += dp[nb][v[i]][v[i + 1]];
            nb += (1 << v[i + 1]);
            n2 += t[v[i]][v[i + 1]];
        }
        if (dp[(1 << 10) - 1][v[9]][11] == INF) ok = false;
        n1 += dp[(1 << 10) - 1][v[9]][11];
        if (!ok) continue;
        if(ans > n1){
            ans = n1;
            ans2 = n2;
        }
        else if(ans == n1 and ans2 < n2){
            ans2 = n2;
        }
    } while (next_permutation(ALL(v)));
    if (ans == INF) cout << -1 << endl;
    else cout << ans << " " << ans2 << endl;
}
accuracy: 1
time_ms: 1030
memory_kb: 5400
final_rank: 10

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;

template <class T, class U>
vector<T> make_v(U size, const T& init){ return vector<T>(static_cast<size_t>(size), init); }

template<class... Ts, class U>
auto make_v(U size, Ts... rest) { return vector<decltype(make_v(rest...))>(static_cast<size_t>(size), make_v(rest...)); }

template<class T> void chmin(T &a, const T &b){ a = (a < b ? a : b); }
template<class T> void chmax(T &a, const T &b){ a = (a > b ? a : b); }

template <class K, class V>
class RadixHeap {
    static constexpr int bit_length = sizeof(K)*8;
    K last;
    size_t sz, cnt;
    array<vector<pair<K, V>>, bit_length> v;
    static inline int bsr(int x){
        return x ? bit_length-__builtin_clz(x) : 0;
    }
    static inline int bsr(ll x){
        return x ? bit_length-__builtin_clzll(x) : 0;
    }

    void pull() {
        if(cnt < v[0].size()) return;;
        int i = 1;
        while(v[i].empty()) i++;
        last = min_element(v[i].begin(),v[i].end())->first;
        for (auto &&x : v[i]) v[bsr(x.first ^ last)].push_back(x);
        v[i].clear();
    }
public:
    RadixHeap() : last(0), sz(0), cnt(0) {}
    void emplace(K x, V val){
        sz++;
        v[bsr(x^last)].emplace_back(x, val);
    }

    pair<K, V> top() {
        pull();
        return v[0][cnt];
    }

    void pop() {
        pull();
        sz--;
        cnt++;
    }

    size_t size() const { return sz; }
    bool empty() const { return !sz; }
};

int main() {
    int w, h;
    cin >> w >> h;
    vector<string> v(h);
    for (auto &&i : v) cin >> i;
    string s = "ST0123456789ABCDEFGHIJabcdefghij";
    array<int, 256> si;
    for (int i = 0; i < s.size(); ++i) si[s[i]] = i;
    vector<int> ys(32, -1), xs(32, -1);
    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            if(v[i][j] == '.' || v[i][j] == '#') continue;
            for (int k = 0; k < s.size(); ++k) {
                if(v[i][j] == s[k]) ys[k] = i, xs[k] = j;
            }
        }
    }
    vector dist(h, vector(w, 0));
    array<int, 4> dy{-1, 1, 0, 0}, dx{0, 0, -1, 1};
    auto in = [&](const int y, const int x){ return 0 <= y && y < h && 0 <= x && x < w && v[y][x] != '#'; };
    vector<vector<pair<int, ll>>> G(32);
    int po[10][10];
    for (auto &&i : po) for(auto &&j : i) cin >> j;
    for (int i = 0; i < 32; ++i) {
        if(!~ys[i]) continue;
        for (auto &&j : dist) fill(j.begin(),j.end(), -1);
        dist[ys[i]][xs[i]] = 0;
        queue<pair<int, int>> Q;
        Q.emplace(ys[i], xs[i]);
        while(!Q.empty()){
            auto [y, x] = Q.front(); Q.pop();
            for (int k = 0; k < 4; ++k) {
                int yy = y+dy[k], xx = x+dx[k];
                if(in(yy, xx)){
                    if(!~dist[yy][xx]){
                        dist[yy][xx] = dist[y][x]+1;
                        if(v[yy][xx] == '.') Q.emplace(yy, xx);
                        else G[i].emplace_back(si[v[yy][xx]], 1000LL*dist[yy][xx]);
                    }
                }
            }
        }
    }
    auto dp = make_v(32, 1 << 10, 10, INF<ll>);
    dp[0][0][0] = 0;
    RadixHeap<ll, int> Q;
    Q.emplace(0, 0);
    auto up = [&](int x, int y, int z, ll val){
        if(dp[x][y][z] <= val) return;
        dp[x][y][z] = val;
        Q.emplace(val, (x << 14)|(y << 4)|z);
    };
    while(!Q.empty()){
        int a, b, c;
        auto [cost, tmp] = Q.top(); Q.pop();
        c = tmp&15, b = (tmp >> 4)&1023, a = (tmp >> 14);
        if(dp[a][b][c] != cost) continue;
        for (auto &&i : G[a]) {
            if(i.first < 2) up(i.first, b, c, cost+i.second);
            else if(i.first < 12){
                up(i.first, b, c, cost+i.second);
                if(b&(1 << (i.first-2))) continue;
                if(!b) up(i.first, 1<<(i.first-2), i.first-2,cost+i.second);
                else up(i.first, b|(1<<(i.first-2)), i.first-2, cost+i.second-po[c][i.first-2]);
            }else if(i.first < 22){
                if(!(b &(1 << (i.first-12))))  up(i.first, b, c, cost+i.second);
            }else {
                if((b & (1 << (i.first-22))))  up(i.first, b, c, cost+i.second);
            }
        }
    }
    ll ans = INF<ll>;
    for (int j = 0; j < 10; ++j) {
        chmin(ans, dp[1].back()[j]);
    }
    if(ans == INF<ll>) puts("-1");
    else {
        ll a = (ans+999)/1000, b = a*1000-ans;
        cout << a << " " << b << "\n";
    }
    return 0;
}
accuracy: 1
time_ms: 360
memory_kb: 16508
final_rank: 7

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;

template <class T, class U>
vector<T> make_v(U size, const T& init){ return vector<T>(static_cast<size_t>(size), init); }

template<class... Ts, class U>
auto make_v(U size, Ts... rest) { return vector<decltype(make_v(rest...))>(static_cast<size_t>(size), make_v(rest...)); }

template<class T> void chmin(T &a, const T &b){ a = (a < b ? a : b); }
template<class T> void chmax(T &a, const T &b){ a = (a > b ? a : b); }

template <class K, class V>
class RadixHeap {
    static constexpr int bit_length = sizeof(K)*8;
    K last;
    size_t sz, cnt;
    array<vector<pair<K, V>>, bit_length> v;
    static inline int bsr(int x){
        return x ? bit_length-__builtin_clz(x) : 0;
    }
    static inline int bsr(ll x){
        return x ? bit_length-__builtin_clzll(x) : 0;
    }

    void pull() {
        if(cnt < v[0].size()) return;;
        int i = 1;
        while(v[i].empty()) i++;
        last = min_element(v[i].begin(),v[i].end())->first;
        for (auto &&x : v[i]) v[bsr(x.first ^ last)].push_back(x);
        v[i].clear();
    }
public:
    RadixHeap() : last(0), sz(0), cnt(0) {}
    void emplace(K x, V val){
        sz++;
        v[bsr(x^last)].emplace_back(x, val);
    }

    pair<K, V> top() {
        pull();
        return v[0][cnt];
    }

    void pop() {
        pull();
        sz--;
        cnt++;
    }

    size_t size() const { return sz; }
    bool empty() const { return !sz; }
};

int main() {
    int w, h;
    cin >> w >> h;
    vector<string> v(h);
    for (auto &&i : v) cin >> i;
    string s = "ST0123456789ABCDEFGHIJabcdefghij";
    array<int, 256> si;
    for (int i = 0; i < s.size(); ++i) si[s[i]] = i;
    vector<int> ys(32, -1), xs(32, -1);
    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            if(v[i][j] == '.' || v[i][j] == '#') continue;
            for (int k = 0; k < s.size(); ++k) {
                if(v[i][j] == s[k]) ys[k] = i, xs[k] = j;
            }
        }
    }
    vector dist(h, vector(w, 0));
    array<int, 4> dy{-1, 1, 0, 0}, dx{0, 0, -1, 1};
    auto in = [&](const int y, const int x){ return 0 <= y && y < h && 0 <= x && x < w && v[y][x] != '#'; };
    vector<vector<pair<int, ll>>> G(32);
    int po[10][10];
    for (auto &&i : po) for(auto &&j : i) cin >> j;
    for (int i = 0; i < 32; ++i) {
        if(!~ys[i]) continue;
        for (auto &&j : dist) fill(j.begin(),j.end(), -1);
        dist[ys[i]][xs[i]] = 0;
        queue<pair<int, int>> Q;
        Q.emplace(ys[i], xs[i]);
        while(!Q.empty()){
            auto [y, x] = Q.front(); Q.pop();
            for (int k = 0; k < 4; ++k) {
                int yy = y+dy[k], xx = x+dx[k];
                if(in(yy, xx)){
                    if(!~dist[yy][xx]){
                        dist[yy][xx] = dist[y][x]+1;
                        if(v[yy][xx] == '.') Q.emplace(yy, xx);
                        else G[i].emplace_back(si[v[yy][xx]], 1000LL*dist[yy][xx]);
                    }
                }
            }
        }
    }
    auto dp = make_v(32, 1 << 10, 10, INF<ll>);
    dp[0][0][0] = 0;
    RadixHeap<ll, int> Q;
    Q.emplace(0, 0);
    auto up = [&](int x, int y, int z, int val){
        if(dp[x][y][z] <= val) return;
        dp[x][y][z] = val;
        Q.emplace(val, (x << 14)|(y << 4)|z);
    };
    while(!Q.empty()){
        int a, b, c;
        auto [cost, tmp] = Q.top(); Q.pop();
        c = tmp&15, b = (tmp >> 4)&1023, a = (tmp >> 14);
        if(dp[a][b][c] != cost) continue;
        for (auto &&i : G[a]) {
            if(i.first < 2) up(i.first, b, c, cost+i.second);
            else if(i.first < 12){
                up(i.first, b, c, cost+i.second);
                if(b&(1 << (i.first-2))) continue;
                if(!b) up(i.first, 1<<(i.first-2), i.first-2,cost+i.second);
                else up(i.first, b|(1<<(i.first-2)), i.first-2, cost+i.second-po[c][i.first-2]);
            }else if(i.first < 22){
                if(!(b &(1 << (i.first-12))))  up(i.first, b, c, cost+i.second);
            }else {
                if((b & (1 << (i.first-22))))  up(i.first, b, c, cost+i.second);
            }
        }
    }
    ll ans = INF<ll>;
    for (int j = 0; j < 10; ++j) {
        chmin(ans, dp[1].back()[j]);
    }
    if(ans == INF<ll>) puts("-1");
    else {
        ll a = (ans+999)/1000, b = a*1000-ans;
        cout << a << " " << b << "\n";
    }
    return 0;
}
accuracy: 0.9318181818181818
time_ms: 360
memory_kb: 16384
final_rank: 14

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;

template <class T, class U>
vector<T> make_v(U size, const T& init){ return vector<T>(static_cast<size_t>(size), init); }

template<class... Ts, class U>
auto make_v(U size, Ts... rest) { return vector<decltype(make_v(rest...))>(static_cast<size_t>(size), make_v(rest...)); }

template<class T> void chmin(T &a, const T &b){ a = (a < b ? a : b); }
template<class T> void chmax(T &a, const T &b){ a = (a > b ? a : b); }

template <class K, class V>
class RadixHeap {
    static constexpr int bit_length = sizeof(K)*8;
    K last;
    size_t sz, cnt;
    array<vector<pair<K, V>>, bit_length> v;
    static inline int bsr(int x){
        return x ? bit_length-__builtin_clz(x) : 0;
    }
    static inline int bsr(ll x){
        return x ? bit_length-__builtin_clzll(x) : 0;
    }

    void pull() {
        if(cnt < v[0].size()) return;;
        int i = 1;
        while(v[i].empty()) i++;
        last = min_element(v[i].begin(),v[i].end())->first;
        for (auto &&x : v[i]) v[bsr(x.first ^ last)].push_back(x);
        v[i].clear();
    }
public:
    RadixHeap() : last(0), sz(0), cnt(0) {}
    void emplace(K x, V val){
        sz++;
        v[bsr(x^last)].emplace_back(x, val);
    }

    pair<K, V> top() {
        pull();
        return v[0][cnt];
    }

    void pop() {
        pull();
        sz--;
        cnt++;
    }

    size_t size() const { return sz; }
    bool empty() const { return !sz; }
};

int main() {
    int w, h;
    cin >> w >> h;
    vector<string> v(h);
    for (auto &&i : v) cin >> i;
    string s = "ST0123456789ABCDEFGHIJabcdefghij";
    array<int, 256> si;
    for (int i = 0; i < s.size(); ++i) si[s[i]] = i;
    vector<int> ys(32, -1), xs(32, -1);
    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            if(v[i][j] == '.' || v[i][j] == '#') continue;
            for (int k = 0; k < s.size(); ++k) {
                if(v[i][j] == s[k]) ys[k] = i, xs[k] = j;
            }
        }
    }
    vector dist(h, vector(w, 0));
    array<int, 4> dy{-1, 1, 0, 0}, dx{0, 0, -1, 1};
    auto in = [&](const int y, const int x){ return 0 <= y && y < h && 0 <= x && x < w && v[y][x] != '#'; };
    vector<vector<pair<int, int>>> G(32);
    int po[10][10];
    for (auto &&i : po) for(auto &&j : i) cin >> j;
    for (int i = 0; i < 32; ++i) {
        if(!~ys[i]) continue;
        for (auto &&j : dist) fill(j.begin(),j.end(), -1);
        dist[ys[i]][xs[i]] = 0;
        queue<pair<int, int>> Q;
        Q.emplace(ys[i], xs[i]);
        while(!Q.empty()){
            auto [y, x] = Q.front(); Q.pop();
            for (int k = 0; k < 4; ++k) {
                int yy = y+dy[k], xx = x+dx[k];
                if(in(yy, xx)){
                    if(!~dist[yy][xx]){
                        dist[yy][xx] = dist[y][x]+1;
                        if(v[yy][xx] == '.') Q.emplace(yy, xx);
                        else G[i].emplace_back(si[v[yy][xx]], 1000*dist[yy][xx]);
                    }
                }
            }
        }
    }
    auto dp = make_v(32, 1 << 10, 10, INF<ll>);
    dp[0][0][0] = 0;
    RadixHeap<ll, int> Q;
    Q.emplace(0, 0);
    auto up = [&](int x, int y, int z, int val){
        if(dp[x][y][z] <= val) return;
        dp[x][y][z] = val;
        Q.emplace(val, (x << 14)|(y << 4)|z);
    };
    while(!Q.empty()){
        int a, b, c;
        auto [cost, tmp] = Q.top(); Q.pop();
        c = tmp&15, b = (tmp >> 4)&1023, a = (tmp >> 14);
        if(dp[a][b][c] != cost) continue;
        for (auto &&i : G[a]) {
            if(i.first < 2) up(i.first, b, c, cost+i.second);
            else if(i.first < 12){
                up(i.first, b, c, cost+i.second);
                if(b&(1 << (i.first-2))) continue;
                if(!b) up(i.first, 1<<(i.first-2), i.first-2,cost+i.second);
                else up(i.first, b|(1<<(i.first-2)), i.first-2, cost+i.second-po[c][i.first-2]);
            }else if(i.first < 22){
                if(!(b &(1 << (i.first-12))))  up(i.first, b, c, cost+i.second);
            }else {
                if((b & (1 << (i.first-22))))  up(i.first, b, c, cost+i.second);
            }
        }
    }
    ll ans = INF<ll>;
    for (int j = 0; j < 10; ++j) {
        chmin(ans, dp[1].back()[j]);
    }
    if(ans == INF<ll>) puts("-1");
    else {
        ll a = (ans+999)/1000, b = a*1000-ans;
        cout << a << " " << b << "\n";
    }
    return 0;
}
accuracy: 0.9318181818181818
time_ms: 370
memory_kb: 16532
final_rank: 15

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;

template <class T, class U>
vector<T> make_v(U size, const T& init){ return vector<T>(static_cast<size_t>(size), init); }

template<class... Ts, class U>
auto make_v(U size, Ts... rest) { return vector<decltype(make_v(rest...))>(static_cast<size_t>(size), make_v(rest...)); }

template<class T> void chmin(T &a, const T &b){ a = (a < b ? a : b); }
template<class T> void chmax(T &a, const T &b){ a = (a > b ? a : b); }

template <class K, class V>
class RadixHeap {
    static constexpr int bit_length = sizeof(K)*8;
    K last;
    size_t sz, cnt;
    array<vector<pair<K, V>>, bit_length> v;
    static inline int bsr(int x){
        return x ? bit_length-__builtin_clz(x) : 0;
    }
    static inline int bsr(ll x){
        return x ? bit_length-__builtin_clzll(x) : 0;
    }

    void pull() {
        if(cnt < v[0].size()) return;;
        int i = 1;
        while(v[i].empty()) i++;
        last = min_element(v[i].begin(),v[i].end())->first;
        for (auto &&x : v[i]) v[bsr(x.first ^ last)].push_back(x);
        v[i].clear();
    }
public:
    RadixHeap() : last(0), sz(0), cnt(0) {}
    void emplace(K x, V val){
        sz++;
        v[bsr(x^last)].emplace_back(x, val);
    }

    pair<K, V> top() {
        pull();
        return v[0][cnt];
    }

    void pop() {
        pull();
        sz--;
        cnt++;
    }

    size_t size() const { return sz; }
    bool empty() const { return !sz; }
};

int main() {
    int w, h;
    cin >> w >> h;
    vector<string> v(h);
    for (auto &&i : v) cin >> i;
    string s = "ST0123456789ABCDEFGHIJabcdefghij";
    array<int, 256> si;
    for (int i = 0; i < s.size(); ++i) si[s[i]] = i;
    vector<int> ys(32, -1), xs(32, -1);
    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            if(v[i][j] == '.' || v[i][j] == '#') continue;
            for (int k = 0; k < s.size(); ++k) {
                if(v[i][j] == s[k]) ys[k] = i, xs[k] = j;
            }
        }
    }
    vector dist(h, vector(w, 0));
    array<int, 4> dy{-1, 1, 0, 0}, dx{0, 0, -1, 1};
    auto in = [&](const int y, const int x){ return 0 <= y && y < h && 0 <= x && x < w && v[y][x] != '#'; };
    vector<vector<pair<int, int>>> G(32);
    int po[10][10];
    for (auto &&i : po) for(auto &&j : i) cin >> j;
    for (int i = 0; i < 32; ++i) {
        if(!~ys[i]) continue;
        for (auto &&j : dist) fill(j.begin(),j.end(), -1);
        dist[ys[i]][xs[i]] = 0;
        queue<pair<int, int>> Q;
        Q.emplace(ys[i], xs[i]);
        while(!Q.empty()){
            auto [y, x] = Q.front(); Q.pop();
            for (int k = 0; k < 4; ++k) {
                int yy = y+dy[k], xx = x+dx[k];
                if(in(yy, xx)){
                    if(!~dist[yy][xx]){
                        dist[yy][xx] = dist[y][x]+1;
                        if(v[yy][xx] == '.') Q.emplace(yy, xx);
                        else G[i].emplace_back(si[v[yy][xx]], 1000*dist[yy][xx]);
                    }
                }
            }
        }
    }
    auto dp = make_v(32, 1 << 10, 10, INF<int>);
    dp[0][0][0] = 0;
    RadixHeap<int, int> Q;
    Q.emplace(0, 0);
    auto up = [&](int x, int y, int z, int val){
        if(dp[x][y][z] <= val) return;
        dp[x][y][z] = val;
        Q.emplace(val, (x << 14)|(y << 4)|z);
    };
    while(!Q.empty()){
        int a, b, c;
        auto [cost, tmp] = Q.top(); Q.pop();
        c = tmp&15, b = (tmp >> 4)&1023, a = (tmp >> 14);
        if(dp[a][b][c] != cost) continue;
        for (auto &&i : G[a]) {
            if(i.first < 2) up(i.first, b, c, cost+i.second);
            else if(i.first < 12){
                up(i.first, b, c, cost+i.second);
                if(b&(1 << (i.first-2))) continue;
                if(!b) up(i.first, 1<<(i.first-2), i.first-2,cost+i.second);
                else up(i.first, b|(1<<(i.first-2)), i.first-2, cost+i.second-po[c][i.first-2]);
            }else if(i.first < 22){
                if(!(b &(1 << (i.first-12))))  up(i.first, b, c, cost+i.second);
            }else {
                if((b & (1 << (i.first-22))))  up(i.first, b, c, cost+i.second);
            }
        }
    }
    int ans = INF<int>;
    for (int j = 0; j < 10; ++j) {
        chmin(ans, dp[1].back()[j]);
    }
    if(ans == INF<int>) puts("-1");
    else {
        int a = (ans+999)/1000, b = a*1000-ans;
        cout << a << " " << b << "\n";
    }
    return 0;
}
accuracy: 0.9318181818181818
time_ms: 360
memory_kb: 11512
final_rank: 13

code_snippet: #include <bits/stdc++.h>

using i64 = long long;

using namespace std;

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

signed main(){
    int w, h;
    cin >> w >> h;
    vector<string> v(h);
    for(int i = 0; i < h; ++i)
        cin >> v[i];
    vector<int> vx(32, -1);
    vector<int> vy(32, -1);
    for(int i = 0; i < h; ++i){
        for(int j = 0; j < w; ++j){
            if('0' <= v[i][j] && v[i][j] <= '9'){
                vx[v[i][j] - '0'] = i;
                vy[v[i][j] - '0'] = j;
            }
            if('a' <= v[i][j] && v[i][j] <= 'j'){
                vx[10 + v[i][j] - 'a'] = i;
                vy[10 + v[i][j] - 'a'] = j;
            }
            if('A' <= v[i][j] && v[i][j] <= 'J'){
                vx[20 + v[i][j] - 'A'] = i;
                vy[20 + v[i][j] - 'A'] = j;
            }
            if(v[i][j] == 'S'){
                vx[30] = i;
                vy[30] = j;
            }
            if(v[i][j] == 'T'){
                vx[31] = i;
                vy[31] = j;
            }
        }
    }
    int m = 10;
    vector<vector<int>> score(m + 1, vector<int>(m + 1, 0));
    for(int i = 0; i < m; ++i)
        for(int j = 0; j < m; ++j)
            cin >> score[i][j];

    vector<int> dx{1, 0, -1, 0};
    vector<int> dy{0, 1, 0, -1};

    auto f = [&](int sx, int sy){
        vector<vector<int>> dist(h, vector<int>(w, 1e9));
        dist[sx][sy] = 0;
        queue<pair<int,int>> que;
        que.emplace(sx, sy);
        while(!que.empty()){
            int x, y;
            tie(x, y) = que.front();
            que.pop();
            for(int d = 0; d < 4; ++d){
                int nx = x + dx[d];
                int ny = y + dy[d];
                if(nx < 0 || ny < 0 || nx >= h || ny >= w)
                    continue;
                if(v[nx][ny] == '#')
                    continue;
                if(dist[nx][ny] > dist[x][y] + 1){
                    dist[nx][ny] = dist[x][y] + 1;
                    if(v[nx][ny] == '.')
                        que.emplace(nx, ny);
                }
            }
        }
        vector<int> wv(32, 1e9);
        for(int i = 0; i < 32; ++i)
            if(vx[i] != -1){
                wv[i] = dist[vx[i]][vy[i]];
            }
        return wv;
    };
    vector<vector<int>> dist(32, vector<int>(32, 1e9));
    for(int i = 0; i < 32; ++i){
        if(vx[i] != -1){
            dist[i] = f(vx[i], vy[i]);
        }
    }
    vector<vector<vector<pair<i64,i64>>>> a(32, vector<vector<pair<i64,i64>>>(1<<m, vector<pair<i64,i64>>(11, {1e18, 0})));
    a[30][0][10] = {0, 0};
    priority_queue<tuple<i64,i64,int,int,int>, vector<tuple<i64,i64,int,int,int>>, greater<tuple<i64,i64,int,int,int>>> que;
    que.emplace(0, 0, 30, 0, 10);
    while(!que.empty()){
        i64 d, sc;
        int i, j, k;
        tie(d, sc, i, j, k) = que.top();
        que.pop();
        if(a[i][j][k] != make_pair(d, sc))
            continue;
        // 0,9 get item
        for(int to = 0; to < 10; ++to){
            if(chmin(a[to][j][k], {d + dist[i][to], sc}))
                que.emplace(d + dist[i][to], sc, to, j, k);
            if(!(j & (1 << to)))
                if(chmin(a[to][j | (1 << to)][to], {d + dist[i][to], sc - score[k][to]}))
                    que.emplace(d + dist[i][to], sc - score[k][to], to, j | (1 << to), to);
        }
        // a,j
        for(int to = 10; to < 20; ++to){
            if(j & (1 << (to - 10))){
                if(chmin(a[to][j][k], {d + dist[i][to], sc}))
                    que.emplace(d + dist[i][to], sc, to, j, k);
            }
        }
        // A,J
        for(int to = 20; to < 30; ++to){
            if(!(j & (1 << (to - 20)))){
                if(chmin(a[to][j][k], {d + dist[i][to], sc})){
                    que.emplace(d + dist[i][to], sc, to, j, k);
                }
            }
        }
        for(int to = 30; to < 32; ++to)
            if(chmin(a[to][j][k], {d + dist[i][to], sc}))
                que.emplace(d + dist[i][to], sc, to, j, k);
    }
    pair<i64,i64> ans(1e18, -1e18);
    for(auto x : a[31][(1 << m) - 1])
        chmin(ans, x);
    if(ans.first >= 1e9)
        cout << -1 << endl;
    else
        cout << ans.first << " " << -ans.second << endl;

    /*
    for(int i = 0; i < 32; ++i){
        for(int j = 0; j < 32; ++j){
            cout << (dist[i][j] >= 100 ? -1 : dist[i][j]) << " \n"[j == 31];
        }
    }
     */
}
accuracy: 1
time_ms: 550
memory_kb: 18284
final_rank: 9

code_snippet: #include <iostream>
#include <queue>
using namespace std;

int H, W, sx[32], sy[32], s[10][10], idx[1009][1009];
char c[1009][1009];
int t[32][32], u[1009][1009];
pair<int, int> dp[1 << 10][32];

int dx[4] = { 1, 0, -1, 0 };
int dy[4] = { 0, 1, 0, -1 };

int main() {
	cin >> W >> H;
	for (int i = 1; i <= H; i++) {
		for (int j = 1; j <= W; j++) {
			cin >> c[i][j]; idx[i][j] = -1;
			if (c[i][j] == 'S') { sx[30] = i; sy[30] = j; }
			if (c[i][j] == 'T') { sx[31] = i; sy[31] = j; }
			if (c[i][j] >= '0' && c[i][j] <= '9') {
				sx[0 + (c[i][j] - '0')] = i;
				sy[0 + (c[i][j] - '0')] = j;
			}
			if (c[i][j] >= 'A' && c[i][j] <= 'J') {
				sx[10 + (c[i][j] - 'A')] = i;
				sy[10 + (c[i][j] - 'A')] = j;
			}
			if (c[i][j] >= 'a' && c[i][j] <= 'z') {
				sx[20 + (c[i][j] - 'a')] = i;
				sy[20 + (c[i][j] - 'a')] = j;
			}
		}
	}
	for (int i = 0; i < 10; i++) {
		for (int j = 0; j < 10; j++) cin >> s[i][j];
	}
	for (int i = 0; i <= 31; i++) { idx[sx[i]][sy[i]] = i; for (int j = 0; j <= 31; j++) t[i][j] = (1 << 25); }

	for (int i = 0; i <= 31; i++) {
		if (sx[i] == 0 && sy[i] == 0) continue;
		for (int j = 1; j <= H; j++) { for (int k = 1; k <= W; k++) u[j][k] = (1 << 25); }

		queue<pair<int, int>> Q;
		Q.push(make_pair(sx[i], sy[i]));
		u[sx[i]][sy[i]] = 0;

		while (!Q.empty()) {
			int cx = Q.front().first, cy = Q.front().second; Q.pop();

			for (int j = 0; j < 4; j++) {
				int ex = cx + dx[j], ey = cy + dy[j];
				if (ex <= 0 || ey <= 0 || ex > H || ey > W || c[ex][ey] == '#') continue;

				if (idx[ex][ey] == -1) {
					if (u[ex][ey] == (1 << 25)) {
						Q.push(make_pair(ex, ey));
						u[ex][ey] = u[cx][cy] + 1;
					}
				}
				else {
					t[i][idx[ex][ey]] = min(t[i][idx[ex][ey]], u[cx][cy] + 1);
				}
			}
		}
	}

	for (int i = 0; i < (1 << 10); i++) {
		for (int j = 0; j < 32; j++) dp[i][j] = make_pair((1 << 25), (1 << 25));
	}
	dp[0][30] = make_pair(0, 0);

	pair<int, int> maxn = make_pair((1 << 25), -1);

	for (int i = 0; i < (1 << 10); i++) {
		for (int j = 0; j < 32; j++) {
			if (dp[i][j] == make_pair((1 << 25), (1 << 25))) continue;

			// 幅優先探索
			int dist[32]; for (int k = 0; k < 32; k++) dist[k] = (1 << 25); dist[j] = 0;
			vector<int> V;
			for (int k = 0; k < 10; k++) V.push_back(k);
			for (int k = 0; k < 10; k++) { if ((i / (1 << k)) % 2 == 0) V.push_back(10 + k); }
			for (int k = 0; k < 10; k++) { if ((i / (1 << k)) % 2 == 1) V.push_back(20 + k); }
			V.push_back(30); V.push_back(31);

			for (int tt = 0; tt < 22; tt++) {
				for (int k : V) {
					for (int l : V) {
						if (t[k][l] == -(1 << 25)) continue;
						dist[l] = min(dist[l], dist[k] + t[k][l]);
					}
				}
			}

			if (i == 1023) {
				maxn = min(maxn, make_pair(dp[i][j].first + dist[31], dp[i][j].second));
			}

			// DP の更新
			for (int k = 0; k < 10; k++) {
				if (dist[k] == (1 << 25) || (i / (1 << k)) % 2 == 1) continue;
				dp[i + (1 << k)][k] = min(dp[i + (1 << k)][k], make_pair(dp[i][j].first + dist[k], dp[i][j].second - s[j][k]));
			}
		}
	}

	if (maxn.first == (1 << 25)) cout << "-1" << endl;
	else cout << maxn.first << " " << -maxn.second << endl;
	return 0;
}
accuracy: 1
time_ms: 500
memory_kb: 12212
final_rank: 8