Problem:
Score : 600 points

Problem Statement

We have N strings of lowercase English letters: S_1, S_2, \cdots, S_N.

Takahashi wants to make a string that is a palindrome by choosing one or more of these strings - the same string can be chosen more than once - and concatenating them in some order of his choice.

The cost of using the string S_i once is C_i, and the cost of using it multiple times is C_i multiplied by that number of times.

Find the minimum total cost needed to choose strings so that Takahashi can make a palindrome.

If there is no choice of strings in which he can make a palindrome, print -1.

Constraints

1 \leq N \leq 50

1 \leq |S_i| \leq 20

S_i consists of lowercase English letters.

1 \leq C_i \leq 10^9

Input

Input is given from Standard Input in the following format:

N
S_1 C_1
S_2 C_2
:
S_N C_N

Output

Print the minimum total cost needed to choose strings so that Takahashi can make a palindrome, or -1 if there is no such choice.

Sample Input 1

3
ba 3
abc 4
cbaa 5

Sample Output 1

7

We have ba, abc, and cbaa.

For example, we can use ba once and abc once for a cost of 7, then concatenate them in the order abc, ba to make a palindrome.
Also, we can use abc once and cbaa once for a cost of 9, then concatenate them in the order cbaa, abc to make a palindrome.

We cannot make a palindrome for a cost less than 7, so we should print 7.

Sample Input 2

2
abcab 5
cba 3

Sample Output 2

11

We can choose abcab once and cba twice, then concatenate them in the order abcab, cba, cba to make a palindrome for a cost of 11.

Sample Input 3

4
ab 5
cba 3
a 12
ab 10

Sample Output 3

8

We can choose a once, which is already a palindrome, but it is cheaper to concatenate ab and cba.

Sample Input 4

2
abc 1
ab 2

Sample Output 4

-1

We cannot make a palindrome, so we should print -1.

Solution in C++ (GCC 9.2.1) (judge verdict: Wrong Answer)

#include<bits/stdc++.h>
#include<string.h>
#define ll long long
#define pf printf
#define sf scanf
#define ff first
#define ss second
#define clr clear()
#define sz size()
#define pb push_back
#define mk make_pair
#define pi acos(-1)
#define inf 2000000000000000000
#define mod 1000000007
#define ull unsigned long long int
#define f(i,k,n) for(i=k;i<n;i++)
#define fr(i,n,k) for(i=n;i>=k;i--)
#define ent(a) scanf("%lld",&a)
#define ent2(a,b) scanf("%lld%lld",&a,&b)
#define ent3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define mem(a) memset(a,0,sizeof(a))
#define vec(v,s) vector<ll>v[s]
#define arr(a,s) ll a[s];
/*#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")*/
//knight and king//
int dr[]= {2,2,-2,-2,1,-1,1,-1};
int dc[]= {1,-1,1,-1,2,2,-2,-2};
int dr1[]= {0,0,1,1,1,-1,-1,-1};
int dc1[]= {1,-1,1,0,-1,0,1,-1};
int dr2[]= {0,0,1,-1};
int dc2[]= {1,-1,0,0};
////////////////////////////
using namespace std;
#define ma 2005

ll a[ma];

ll tr[2][1004][26],node[2],b[2][55][1005];
ll len[2][ma];
ll co[2][ma],en[2][ma];
void inser(string t,ll x,ll f,ll c)
{
    ll i,j,now=1;
    b[f][x][now]=1;
    for(i=0; i<t.sz; i++)
    {
        ll p=t[i]-'a';
        if(tr[f][now][p]==0)
        {
            tr[f][now][p]=++node[f];
            len[f][node[f]]=len[f][now]+1;
        }
        now=tr[f][now][p];
        b[f][x][now]=1;
    }
    if(co[f][now]==0)
        co[f][now]=c;
    else
        co[f][now]=min(co[f][now],c);
}
string t[ma],rt[ma];
ll d[ma];
ll cost[ma][ma];
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    ll i,j,x,y,z,n,tc,k,k1;
    while(cin>>n)
    {
        node[0]=node[1]=1;
        ll min1=inf;
        for(i=1; i<=n; i++)
        {
            cin>>t[i]>>d[i];
            inser(t[i],i,0,d[i]);
            rt[i]=t[i];
            reverse(rt[i].begin(),rt[i].end());
            if(t[i]==rt[i])min1=min(min1,d[i]);
            inser(rt[i],i,1,d[i]);
        }

        queue<ll>q;
        q.push(1);
        q.push(1);
        memset(cost,inf,sizeof(cost));
        for(i=0; i<ma; i++)
            for(j=0; j<ma; j++)
                cost[i][j]=inf;
        cost[1][1]=0;
        while(q.sz>0)
        {
            ll u=q.front();
            q.pop();
            ll v=q.front();
            q.pop();


            for(i=0; i<26; i++)
            {
                ll p=tr[0][u][i];
                ll q1=tr[1][v][i];
                if(p==0||q1==0)
                    continue;
                vector<ll>v1,v2;
                v1.pb(p);
                v2.pb(q1);
                if(co[0][p]!=0)
                    v1.pb(1);
                if(co[1][q1]!=0)
                    v2.pb(1);
                for(auto j1:v1)
                {
                    for(auto j2:v2)
                    {
                        ll dum=0;
                        if(co[0][p])
                            dum+=co[0][p];
                        if(j2==1)
                            dum+=co[1][q1];
                        if(j1==1&&j2==1&&cost[j1][j2]==0)
                        {
                            cost[j1][j2]=dum;
                            continue;
                        }
                        if(cost[j1][j2]>cost[u][v]+dum)
                        {
                            cost[j1][j2]=cost[u][v]+dum;
                            q.push(j1);
                            q.push(j2);
                        }
                    }
                }
            }
        }

        if(cost[1][1]!=0)min1=cost[1][1];

       for(i=2;i<=node[1];i++)
       {
           if(cost[1][i]!=inf)
           {
               ll p=len[1][i];
               for(j=1;j<=n;j++)
               {
                   if(b[1][j][i]==0)continue;
                   string t1="";
                   for(k=p;k<t[j].sz;k++)t1+=t[j][k];
                   string t2=t1;
                   reverse(t2.begin(),t2.end());
                   if(t1==t2)min1=min(min1,cost[1][i]+d[j]);
               }
           }
       }


        for(i=2;i<=node[0];i++)
       {
           if(cost[i][1]!=inf)
           {
               ll p=len[0][i];
               for(j=1;j<=n;j++)
               {
                   if(b[0][j][i]==0)continue;
                   string t1="";
                   for(k=p;k<t[j].sz;k++)t1+=t[j][k];
                   string t2=t1;
                   reverse(t2.begin(),t2.end());
                   if(t1==t2)min1=min(min1,cost[i][1]+d[j]);
               }
           }
       }

       if(min1==inf)min1=-1;


       cout<<min1<<endl;











    }
    return 0;
}