#include<bits/stdc++.h>
using namespace std;
long long a[1000000];
string sarr[1000000];
string rs[1000000];
long long dp[1000000][10];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    string str;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
        for(int i=0;i<n;i++)
        {
            cin>>str;
            sarr[i]=str;
            reverse(str.begin(),str.end());
            rs[i]=str;
        }
        for(int i=1;i<n;i++)
        {
            dp[i][0]=INFINITY;
            dp[i][1]=INFINITY;
        }
        dp[0][0]=0;
        dp[0][1]=a[0];
        for(int i=1;i<n;i++)
        {
            if(sarr[i]>=sarr[i-1])
                dp[i][0]=min(dp[i][0],dp[i-1][0]);
                if(sarr[i]>=rs[i-1])
                    dp[i][0]=min(dp[i][0],dp[i-1][1]);
                if(rs[i]>=sarr[i-1])
                dp[i][1]=min(dp[i][1],dp[i-1][0]+a[i]);
        if(rs[i]>=rs[i-1])
            dp[i][1]=min(dp[i][1],dp[i-1][1]+a[i]);
        }
 /*       for(int i=0;i<n;i++)
        {
            for(int j=0;j<2;j++)
                cout<<dp[i][j]<<" ";
            cout<<endl;
        }
*/
        if(dp[n-1][0]==INFINITY&&dp[n-1][1]==INFINITY)
            cout<<"-1\n";
        else
        cout<<min(dp[n-1][0],dp[n-1][1])<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
long long a[1000000];
string sarr[1000000];
string rs[1000000];
long long dp[1000000][10];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    string str;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
        for(int i=0;i<n;i++)
        {
            cin>>str;
            sarr[i]=str;
            reverse(str.begin(),str.end());
            rs[i]=str;
        }
        dp[0][0]=0;
        dp[0][1]=a[0];
        for(int i=1;i<n;i++)
        {
            dp[i][0]=LLONG_MAX;
            dp[i][1]=LLONG_MAX;
            if(sarr[i]>=sarr[i-1])
                dp[i][0]=min(dp[i][0],dp[i-1][0]);
                if(sarr[i]>=rs[i-1])
                    dp[i][0]=min(dp[i][0],dp[i-1][1]);
                if(rs[i]>=sarr[i-1])
                dp[i][1]=min(dp[i][1],dp[i-1][0]+a[i]);
        if(rs[i]>=rs[i-1])
            dp[i][1]=min(dp[i][1],dp[i-1][1]+a[i]);
        }
        /*
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<2;j++)
                cout<<dp[i][j]<<" ";
            cout<<endl;
        }
        */
        if(dp[n-1][0]==LLONG_MAX&&dp[n-1][1]==LLONG_MAX)
            cout<<"-1\n";
        else
        cout<<min(dp[n-1][0],dp[n-1][1])<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
long long a[1000000];
string sarr[1000000];
string rs[1000000];
long long dp[1000000][10];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    string str;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
        for(int i=0;i<n;i++)
        {
            cin>>str;
            sarr[i]=str;
            reverse(str.begin(),str.end());
            rs[i]=str;
        }
        for(int i=0;i<n;i++)
        {
            dp[i][0]=LLONG_MAX;
            dp[i][1]=LLONG_MAX;
        }
        dp[0][0]=0;
        dp[0][1]=a[0];
        for(int i=1;i<n;i++)
        {
            if(sarr[i]>=sarr[i-1])
                dp[i][0]=min(dp[i][0],dp[i-1][0]);
                if(sarr[i]>=rs[i-1])
                    dp[i][0]=min(dp[i][0],dp[i-1][1]);
                if(rs[i]>=sarr[i-1])
                dp[i][1]=min(dp[i][1],dp[i-1][0]+a[i]);
        if(rs[i]>=rs[i-1])
            dp[i][1]=min(dp[i][1],dp[i-1][0]+a[i]+dp[i-1][1]);
        }
        /*
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<2;j++)
                cout<<dp[i][j]<<" ";
            cout<<endl;
        }
        */
        if(dp[n-1][0]==LLONG_MAX&&dp[n-1][1]==LLONG_MAX)
            cout<<"-1\n";
        else
        cout<<min(dp[n-1][0],dp[n-1][1])<<endl;
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;

const int mxN = 1e5 + 5, INF = 1e18;
long long new_Cost[mxN], new_Reversed[mxN], cost[mxN];
string str[mxN], rev[mxN];
int main() {
	int n;
	cin >> n;
	for(int i = 0; i < n; ++i)
		scanf("%d", cost + i);
	for(int i = 0; i < n; ++i) {
		cin >> rev[i];
		str[i] = rev[i];
		reverse(rev[i].begin(), rev[i].end());
		new_Cost[i] = new_Reversed[i] = INF;
	}
	new_Cost[0] = 0, new_Reversed[0] = cost[0];
	bool valid = false;
	for(int i = 1; i < n; ++i) {
		// try with the current string to reverse the previous and the same previous, and new_Cost[i] will be the minimum.
		valid = false;
		if(new_Cost[i - 1] != INF && str[i - 1] <= rev[i])
			new_Reversed[i] = new_Cost[i - 1] + cost[i], valid = true;
		if(rev[i - 1] <= rev[i])
			new_Reversed[i] = min(new_Reversed[i], new_Reversed[i - 1] + cost[i]), valid = true;
		// try 	the current string without reverse.
		if(new_Cost[i - 1] != INF && str[i - 1] <= str[i])
			new_Cost[i] = new_Cost[i - 1], valid = true;
		if(rev[i - 1] <= str[i])
			new_Cost[i] = min(new_Cost[i], new_Reversed[i - 1]), valid = true;
		if(rev[i] < str[i - 1] && rev[i] < rev[i - 1] && str[i] < rev[i - 1] && str[i] < str[i - 1])
			return cout << -1, 0;
	}
	cout << min(new_Cost[n - 1], new_Reversed[n - 1]);
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;

const int mxN = 1e5 + 5, INF = 1e18;
long long new_Cost[mxN], new_Reversed[mxN], cost[mxN];
string str[mxN], rev[mxN];
int main() {
	int n;
	cin >> n;
	for(int i = 1; i <= n; ++i)
		scanf("%d", cost + i);
	for(int i = 1; i <= n; ++i) {
		cin >> rev[i];
		str[i] = rev[i];
		reverse(rev[i].begin(), rev[i].end());
		new_Cost[i] = new_Reversed[i] = INF;
	}
	for(int i = 0; i < mxN; ++i)
		str[0] += 'A', rev[0] += 'A';
	new_Cost[1] = 0, new_Reversed[1] = cost[1];
	bool valid = false;
	for(int i = 2; i <= n; ++i) {
		// try with the current string to reverse the previous and the same previous, and new_Cost[i] will be the minimum.
		valid = false;
		if(new_Cost[i - 1] != INF &&  str[i - 1] <= rev[i])
			new_Reversed[i] = new_Cost[i - 1] + cost[i], valid = true;
		if(rev[i - 1] <= rev[i])
			new_Reversed[i] = min(new_Reversed[i], new_Reversed[i - 1] + cost[i]), valid = true;

		// try 	the current string without reverse.
		if(new_Cost[i - 1] != INF && str[i - 1] <= str[i])
			new_Cost[i] = new_Cost[i - 1], valid = true;
		if(rev[i - 1] <= str[i])
			new_Cost[i] = min(new_Cost[i], new_Reversed[i - 1]), valid = true;
		if(!valid)
			return -1, 0;
	}
	cout << min(new_Cost[n], new_Reversed[n]);
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;

const int mxN = 1e5 + 5, INF = 1e18;
long long new_Cost[mxN], new_Reversed[mxN], cost[mxN];
string str[mxN], rev[mxN];
int main() {
	int n;
	cin >> n;
	for(int i = 1; i <= n; ++i)
		scanf("%d", cost + i);
	for(int i = 1; i <= n; ++i) {
		cin >> rev[i];
		str[i] = rev[i];
		reverse(rev[i].begin(), rev[i].end());
		new_Cost[i] = new_Reversed[i] = INF;
	}
	for(int i = 0; i < mxN; ++i)
		str[0] += 'A', rev[0] += 'A';
	new_Cost[1] = 0, new_Reversed[1] = cost[1];
	bool valid = false;
	for(int i = 2; i <= n; ++i) {
		// try with the current string to reverse the previous and the same previous, and new_Cost[i] will be the minimum.
		valid = false;
		bool check = (str[i - 1] >= str[i - 2] || str[i - 1] >= rev[i - 2]),
			 check2 = (rev[i - 1] >= rev[i - 2] || rev[i - 1] >= str[i - 2]);
		if(check && str[i - 1] <= rev[i])
			new_Reversed[i] = new_Cost[i - 1] + cost[i], valid = true;
		if(rev[i - 1] <= rev[i] && check2)
			new_Reversed[i] = min(new_Reversed[i], new_Reversed[i - 1] + cost[i]), valid = true;

		// try 	the current string without reverse.
		if(check && str[i - 1] <= str[i])
			new_Cost[i] = new_Cost[i - 1], valid = true;
		if(rev[i - 1] <= str[i] && check2)
			new_Cost[i] = min(new_Cost[i], new_Reversed[i - 1]), valid = true;
		if(!valid)
			return cout << -1, 0;
	}
	cout << min(new_Cost[n], new_Reversed[n]);
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;

const int mxN = 1e5 + 5, INF = 1e18;
long long new_Cost[mxN], new_Reversed[mxN], cost[mxN];
string str[mxN], rev[mxN];
int main() {
	int n;
	cin >> n;
	for(int i = 1; i <= n; ++i)
		scanf("%d", cost + i);
	for(int i = 1; i <= n; ++i) {
		cin >> rev[i];
		str[i] = rev[i];
		reverse(rev[i].begin(), rev[i].end());
		new_Cost[i] = new_Reversed[i] = INF;
	}
	for(int i = 0; i < mxN; ++i)
		str[0] += 'A', rev[0] += 'A';
	new_Cost[1] = 0, new_Reversed[1] = cost[1];
	bool valid = false;
	for(int i = 2; i <= n; ++i) {
		// try with the current string to reverse the previous and the same previous, and new_Cost[i] will be the minimum.
		valid = false;
		bool check = (str[i - 1] >= str[i - 2] || str[i - 1] >= rev[i - 2]) && new_Cost[i - 1] != INF;
		if(check &&  str[i - 1] <= rev[i])
			new_Reversed[i] = new_Cost[i - 1] + cost[i], valid = true;
		if(rev[i - 1] <= rev[i])
			new_Reversed[i] = min(new_Reversed[i], new_Reversed[i - 1] + cost[i]), valid = true;

		// try 	the current string without reverse.
		if(check && str[i - 1] <= str[i])
			new_Cost[i] = new_Cost[i - 1], valid = true;
		if(rev[i - 1] <= str[i])
			new_Cost[i] = min(new_Cost[i], new_Reversed[i - 1]), valid = true;
		if(!valid)
			return cout << -1, 0;
	}
	cout << min(new_Cost[n], new_Reversed[n]);
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;

const int mxN = 1e5 + 5, INF = 1e18;
long long new_Cost[mxN], new_Reversed[mxN], cost[mxN];
string str[mxN], rev[mxN];
int main() {
	int n;
	cin >> n;
	for(int i = 0; i < n; ++i)
		scanf("%d", cost + i);
	for(int i = 0; i < n; ++i) {
		cin >> rev[i];
		str[i] = rev[i];
		reverse(rev[i].begin(), rev[i].end());
		new_Cost[i] = new_Reversed[i] = INF;
	}
	new_Cost[0] = 0, new_Reversed[0] = cost[0];
	bool valid = false;
	for(int i = 1; i < n; ++i) {
		// try with the current string to reverse the previous and the same previous, and new_Cost[i] will be the minimum.
		valid = false;
		if(new_Cost[i - 1] != INF && str[i - 1] <= rev[i])
			new_Reversed[i] = new_Cost[i - 1] + cost[i], valid = true;
		if(rev[i - 1] <= rev[i])
			new_Reversed[i] = min(new_Reversed[i], new_Reversed[i - 1] + cost[i]), valid = true;
		// try 	the current string without reverse.
		if(new_Cost[i - 1] != INF && str[i - 1] <= str[i])
			new_Cost[i] = new_Cost[i - 1], valid = true;
		if(rev[i - 1] <= str[i])
			new_Cost[i] = min(new_Cost[i], new_Reversed[i - 1]), valid = true;
		if(!valid)
			return cout << -1, 0;
	}
	cout << min(new_Cost[n - 1], new_Reversed[n - 1]);
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;

const int mxN = 1e5 + 5, INF = 1e18;
long long new_Cost[mxN], new_Reversed[mxN], cost[mxN];
string str[mxN], rev[mxN];
int main() {
	int n;
	cin >> n;
	for(int i = 0; i < n; ++i)
		scanf("%d", cost + i);
	for(int i = 0; i < n; ++i) {
		cin >> rev[i];
		str[i] = rev[i];
		reverse(rev[i].begin(), rev[i].end());
		new_Cost[i] = new_Reversed[i] = INF;
	}
	new_Cost[0] = 0, new_Reversed[0] = cost[0];
	if(n > 1) {
		if(str[0] > str[1])
			new_Cost[0] = INF, new_Reversed[0] = cost[0];
	}
	bool valid = false;
	for(int i = 1; i < n; ++i) {
		// try with the current string to reverse the previous and the same previous, and new_Cost[i] will be the minimum.
		valid = false;
		if(new_Cost[i - 1] != INF && str[i - 1] <= rev[i])
			new_Reversed[i] = new_Cost[i - 1] + cost[i], valid = true;
		if(rev[i - 1] <= rev[i])
			new_Reversed[i] = min(new_Reversed[i], new_Reversed[i - 1] + cost[i]), valid = true;
		// try 	the current string without reverse.
		if(new_Cost[i - 1] != INF && str[i - 1] <= str[i])
			new_Cost[i] = new_Cost[i - 1], valid = true;
		if(rev[i - 1] <= str[i])
			new_Cost[i] = min(new_Cost[i], new_Reversed[i - 1]), valid = true;
		if(!valid)
			return cout << -1, 0;
	}
	cout << min(new_Cost[n - 1], new_Reversed[n - 1]);
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;

const long long mxN = 1e5 + 5, INF = 1e18;
long long new_Cost[mxN], new_Reversed[mxN], cost[mxN];
string str[mxN], rev[mxN];
int main() {
	int n;
	cin >> n;
	for(int i = 1; i <= n; ++i)
		scanf("%d", cost + i);
	for(int i = 1; i <= n; ++i) {
		cin >> rev[i];
		str[i] = rev[i];
		reverse(rev[i].begin(), rev[i].end());
		new_Cost[i] = new_Reversed[i] = INF;
	}
	for(int i = 0; i < mxN; ++i)
		str[0] += 'A', rev[0] += 'A';
	new_Cost[1] = 0, new_Reversed[1] = cost[1];
	bool valid = false;
	for(int i = 2; i <= n; ++i) {
		// try with the current string to reverse the previous and the same previous, and new_Cost[i] will be the minimum.
		valid = false;
		bool check = (str[i - 1] >= str[i - 2] || str[i - 1] >= rev[i - 2]); // if true then previous string not a must to be reversed.
		// you need to know if you MUST reverse the previous string or not

		if(check && str[i - 1] <= rev[i])
			new_Reversed[i] = new_Cost[i - 1] + cost[i], valid = true;
		if(rev[i - 1] <= rev[i])
			new_Reversed[i] = min(new_Reversed[i], new_Reversed[i - 1] + cost[i]), valid = true;

		// try 	the current string without reverse.
		if(check && str[i - 1] <= str[i])
			new_Cost[i] = new_Cost[i - 1], valid = true;
		if(rev[i - 1] <= str[i])
			new_Cost[i] = min(new_Cost[i], new_Reversed[i - 1]), valid = true;
		if(!valid)
			return cout << -1, 0;
	}
	cout << min(new_Cost[n], new_Reversed[n]);
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;

const int mxN = 1e5 + 5, INF = 1e18;
long long new_Cost[mxN], new_Reversed[mxN], cost[mxN];
string str[mxN], rev[mxN];
int main() {
	int n;
	cin >> n;
	for(int i = 1; i <= n; ++i)
		scanf("%d", cost + i);
	for(int i = 1; i <= n; ++i) {
		cin >> rev[i];
		str[i] = rev[i];
		reverse(rev[i].begin(), rev[i].end());
		new_Cost[i] = new_Reversed[i] = INF;
	}
	for(int i = 0; i < mxN; ++i)
		str[0] += 'A', rev[0] += 'A';
	new_Cost[1] = 0, new_Reversed[1] = cost[1];
	bool valid = false;
	for(int i = 2; i <= n; ++i) {
		// try with the current string to reverse the previous and the same previous, and new_Cost[i] will be the minimum.
		valid = false;
		if(new_Cost[i - 1] != INF &&  str[i - 1] <= rev[i])
			new_Reversed[i] = new_Cost[i - 1] + cost[i], valid = true;
		if(rev[i - 1] <= rev[i])
			new_Reversed[i] = min(new_Reversed[i], new_Reversed[i - 1] + cost[i]), valid = true;

		// try 	the current string without reverse.
		if(new_Cost[i - 1] != INF && str[i - 1] <= str[i])
			new_Cost[i] = new_Cost[i - 1], valid = true;
		if(rev[i - 1] <= str[i])
			new_Cost[i] = min(new_Cost[i], new_Reversed[i - 1]), valid = true;
		if(!valid)
			return cout << -1, 0;
	}
	cout << min(new_Cost[n], new_Reversed[n]);
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;

const int mxN = 1e5 + 5, INF = 1e18;
long long new_Cost[mxN], new_Reversed[mxN], cost[mxN];
string str[mxN], rev[mxN];
int main() {
	int n;
	cin >> n;
	for(int i = 0; i < n; ++i)
		scanf("%d", cost + i);
	for(int i = 0; i < n; ++i) {
		cin >> rev[i];
		str[i] = rev[i];
		reverse(rev[i].begin(), rev[i].end());
		new_Cost[i] = new_Reversed[i] = INF;
	}
	new_Cost[0] = 0, new_Reversed[0] = cost[0];
	bool valid = false;
	for(int i = 1; i < n; ++i) {
		// try with the current string to reverse the previous and the same previous, and new_Cost[i] will be the minimum.
		valid = false;
		if(new_Cost[i - 1] != INF && str[i - 1] <= rev[i])
			new_Reversed[i] = new_Cost[i - 1] + cost[i], valid = true;
		if(rev[i - 1] <= rev[i])
			new_Reversed[i] = min(new_Reversed[i], new_Reversed[i - 1] + cost[i]), valid = true;
		// try 	the current string without reverse.
		if(new_Cost[i - 1] != INF && str[i - 1] <= str[i])
			new_Cost[i] = new_Cost[i - 1], valid = true;
		if(rev[i - 1] <= str[i])
			new_Cost[i] = min(new_Cost[i], new_Reversed[i - 1]), valid = true;
		if(rev[i] < str[i - 1] && rev[i] < rev[i - 1] && str[i] < rev[i - 1] && str[i] < rev[i - 1])
			return cout << -1, 0;
	}
	cout << min(new_Cost[n - 1], new_Reversed[n - 1]);
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;

const int mxN = 1e5 + 5, INF = 1e18;
long long new_Cost[mxN], new_Reversed[mxN], cost[mxN];
string str[mxN], rev[mxN];
int main() {
	int n;
	cin >> n;
	for(int i = 1; i <= n; ++i)
		scanf("%d", cost + i);
	for(int i = 1; i <= n; ++i) {
		cin >> rev[i];
		str[i] = rev[i];
		reverse(rev[i].begin(), rev[i].end());
		new_Cost[i] = new_Reversed[i] = INF;
	}
	for(int i = 0; i < mxN; ++i)
		str[0] += 'A', rev[0] += 'A';
	new_Cost[1] = 0, new_Reversed[1] = cost[1];
	bool valid = false;
	for(int i = 2; i <= n; ++i) {
		// try with the current string to reverse the previous and the same previous, and new_Cost[i] will be the minimum.
		valid = false;
		bool check = (str[i - 1] >= str[i - 2] || str[i - 1] >= rev[i - 2]); // if true then previous string can be reversed or not.
		if(check && str[i - 1] <= rev[i])
			new_Reversed[i] = new_Cost[i - 1] + cost[i], valid = true;
		if(rev[i - 1] <= rev[i])
			new_Reversed[i] = min(new_Reversed[i], new_Reversed[i - 1] + cost[i]), valid = true;

		// try 	the current string without reverse.
		if(check && str[i - 1] <= str[i])
			new_Cost[i] = new_Cost[i - 1], valid = true;
		if(rev[i - 1] <= str[i])
			new_Cost[i] = min(new_Cost[i], new_Reversed[i - 1]), valid = true;
		if(!valid || new_Cost[i] == INF || new_Reversed[i] == INF)
			return cout << -1, 0;

	}
	cout << min(new_Cost[n], new_Reversed[n]);
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;

const int mxN = 1e5 + 5, INF = 1e18;
long long new_Cost[mxN], new_Reversed[mxN], cost[mxN];
string str[mxN], rev[mxN];
int main() {
	int n;
	cin >> n;
	for(int i = 0; i < n; ++i)
		scanf("%d", cost + i);
	for(int i = 0; i < n; ++i) {
		cin >> rev[i];
		str[i] = rev[i];
		reverse(rev[i].begin(), rev[i].end());
		new_Cost[i] = new_Reversed[i] = INF;
	}
	new_Cost[0] = 0, new_Reversed[0] = cost[0];
	for(int i = 1; i < n; ++i) {
		if(new_Cost[i - 1] != INF && str[i - 1] <= rev[i])
			new_Reversed[i] = new_Cost[i - 1] + cost[i];
		if(new_Reversed[i - 1] != INF && rev[i - 1] <= rev[i])
			new_Reversed[i] = min(new_Reversed[i], new_Reversed[i - 1] + cost[i]);

		if(new_Cost[i - 1] != INF && str[i - 1] <= str[i])
			new_Cost[i] = new_Cost[i - 1];
		if(new_Reversed[i - 1] != INF && rev[i - 1] <= str[i])
			new_Cost[i] = min(new_Cost[i], new_Reversed[i - 1]);

		if(new_Cost[i] == new_Reversed[i] && new_Cost[i] == INF)
			return cout << -1, 0;
	}
	cout << min(new_Cost[n - 1], new_Reversed[n - 1]);
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;

const int mxN = 1e5 + 5, INF = 1e18;
long long new_Cost[mxN], new_Reversed[mxN], cost[mxN];
string str[mxN], rev[mxN];
bool same[mxN], revv[mxN];
int main() {
	int n;
	cin >> n;
	for(int i = 1; i <= n; ++i)
		scanf("%d", cost + i);
	for(int i = 1; i <= n; ++i) {
		cin >> rev[i];
		str[i] = rev[i];
		reverse(rev[i].begin(), rev[i].end());
		new_Cost[i] = new_Reversed[i] = INF;
	}
	for(int i = 0; i < mxN; ++i)
		str[0] += 'A', rev[0] += 'A';
	new_Cost[1] = 0, new_Reversed[1] = cost[1];
	same[1] = revv[1] = true;
	for(int i = 2; i <= n; ++i) {
		if(same[i - 1] && str[i - 1] <= rev[i])
			new_Reversed[i] = new_Cost[i - 1] + cost[i], revv[i] = true;
		if(revv[i - 1] && rev[i - 1] <= rev[i])
			new_Reversed[i] = min(new_Reversed[i], new_Reversed[i - 1] + cost[i]), revv[i] = true;

		if(same[i - 1] && str[i - 1] <= str[i])
			new_Cost[i] = new_Cost[i - 1], same[i] = true;
		if(revv[i - 1] && rev[i - 1] <= str[i])
			new_Cost[i] = min(new_Cost[i], new_Reversed[i - 1]), same[i] = true;

		if(new_Cost[i] == new_Reversed[i] && new_Cost[i] == INF)
			return cout << -1, 0;
	}
	cout << min(new_Cost[n], new_Reversed[n]);
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;

const int mxN = 1e5 + 5, INF = 1e18;
long long new_Cost[mxN], new_Reversed[mxN], cost[mxN];
string str[mxN], rev[mxN];
int main() {
	int n;
	cin >> n;
	for(int i = 1; i <= n; ++i)
		scanf("%d", cost + i);
	for(int i = 1; i <= n; ++i) {
		cin >> rev[i];
		str[i] = rev[i];
		reverse(rev[i].begin(), rev[i].end());
		new_Cost[i] = new_Reversed[i] = INF;
	}
	for(int i = 0; i < mxN; ++i)
		str[0] += 'A', rev[0] += 'A';
	new_Cost[1] = 0, new_Reversed[1] = cost[1];
	bool valid = false;
	for(int i = 2; i <= n; ++i) {
		// try with the current string to reverse the previous and the same previous, and new_Cost[i] will be the minimum.
		valid = false;
		bool check = (str[i - 1] >= str[i - 2] || str[i - 1] >= rev[i - 2]); // if true then previous string not a must to be reversed.
		// you need to know if you MUST reverse the previous string or not

		if(check && str[i - 1] <= rev[i])
			new_Reversed[i] = new_Cost[i - 1] + cost[i], valid = true;
		if(rev[i - 1] <= rev[i])
			new_Reversed[i] = min(new_Reversed[i], new_Reversed[i - 1] + cost[i]), valid = true;

		// try 	the current string without reverse.
		if(check && str[i - 1] <= str[i])
			new_Cost[i] = new_Cost[i - 1], valid = true;
		if(rev[i - 1] <= str[i])
			new_Cost[i] = min(new_Cost[i], new_Reversed[i - 1]), valid = true;
		if(!valid)
			return cout << -1, 0;
	}
	cout << min(new_Cost[n], new_Reversed[n]);
}


#include <cstdio>
#include <cstring>
#include <algorithm>
const int NMAX = 100000;
using namespace std;
long long dp[NMAX+5][5];
int c[NMAX+5];
char s1[NMAX+5], s2[NMAX+5];
inline int cmp1 ( char r1[], char s[] ) {
    int n1, n2, i;
    n1 = strlen ( r1 );
    n2 = strlen ( s );
    n1--;
    i = 0;
    while ( r1[n1] == s[i] && n1 >= 0 && i < n2 ) {
        i++;
        n1--;
    }
    if ( n1 < 0 && i == n2 )
        return 0;
    else if ( n1 < 0 )
        return -1;
    else if ( i == n2 )
        return 1;
    else if ( r1[n1] > s[i] )
        return 1;
    return -1;
}
inline int cmp2 ( char r1[], char r2[] ) {
    int n1, n2;
    n1 = strlen ( r1 );
    n2 = strlen ( r2 );
    n1--;
    n2--;
    while ( r1[n1] == r2[n2] && n1 >= 0 && n2 >= 0 ) {
        n2--;
        n1--;
    }
    if ( n1 < 0 && n2 < 0 )
        return 0;
    if ( n1 < 0 )
        return -1;
    else if ( n2 < 0 )
        return 1;
    else if ( r1[n1] > r2[n2] )
        return 1;
    return -1;
}
inline int cmp3 ( char a1[], char a2[] ) {
    int n1, n2, i, j;
    n1 = strlen ( a1 );
    n2 = strlen ( a2 );
    i = j = 0;
    while ( a1[i] == a2[j] && i < n1 && j < n2 ) {
        i++;
        j++;
    }
    if ( i == n1 && j == n2 )
        return 0;
    else if ( i == n1 )
        return -1;
    else if ( j == n2 )
        return 1;
    else if ( a1[i] > a2[j] )
        return 1;
    return -1;
}
int main() {
    int n, i, j, k, n1, n2;
    scanf ( "%d", &n );
    for ( i = 1 ; i <= n ;  ++ i )
        scanf ( "%d", &c[i] );
    getc ( stdin );
    gets ( s1 );
    n1 = strlen ( s1 );
    dp[1][0] = 0;
    dp[1][1] = c[1];
    for ( i = 2 ; i <= n ; ++ i ) {

        gets ( s2 );

        /// dp[i][0]
        if ( cmp3 ( s1, s2 ) <= 0 && dp[i-1][0] != -1 )
            dp[i][0] += dp[i-1][0];
        else if ( cmp1 ( s1, s2 ) <= 0 && dp[i-1][1] != -1 )
            dp[i][0] += dp[i-1][1];
        else
            dp[i][0] = -1;

        /// dp[i][1]
        if ( cmp1 ( s2, s1 ) >= 0 && dp[i-1][0] != -1 )
            dp[i][1] += 1LL * ( dp[i-1][0] + 1LL * c[i] );
        else if ( cmp2 ( s1, s2 ) <= 0 && dp[i-1][1] != -1 )
            dp[i][1] += 1LL * ( dp[i-1][1] + 1LL * c[i] );
        else
            dp[i][1] = -1;

        memset ( s1, 0, sizeof ( s2 ) );
        strcpy ( s1, s2 );
        memset ( s2, 0, sizeof ( s2 ) );
    }
    if ( dp[n][0] == -1 ) {
        if ( dp[n][1] == -1 )
            printf ( "-1\n" );
        else
            printf ( "%I64d\n", dp[n][1] );
    }
    else if ( dp[n][1] == -1 )
        printf ( "%I64d\n", dp[n][0] );
    else
        printf ( "%I64d\n", min ( dp[n][0], dp[n][1] ) );
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
const int NMAX = 100000;
using namespace std;
int dp[NMAX+5][5];
int c[NMAX+5];
char s1[NMAX+5], s2[NMAX+5];
char ras1[NMAX+5], ras2[NMAX+5];
int main() {
    //freopen ( "hard.in", "r", stdin );
    //freopen ( "hard.out", "w", stdout );
    int n, i, j, k, n1, n2;
    scanf ( "%d", &n );
    for ( i = 1 ; i <= n ;  ++ i )
        scanf ( "%d", &c[i] );
    getc ( stdin );
    gets ( s1 );
    n1 = strlen ( s1 );
    j = n1;
    for ( i = 0 ; i < n1 ; ++ i )
        ras1[i] = s1[--j];
    dp[1][0] = 0;
    dp[1][1] = c[1];
    for ( i = 2 ; i <= n ; ++ i ) {

        gets ( s2 );
        n2 = strlen ( s2 );
        k = n2;
        for ( j = 0 ; j < n2 ; ++ j )
            ras2[j] = s2[--k];

        /// dp[i][0]
        if ( strcmp ( s1, s2 ) <= 0 )
            dp[i][0] += dp[i-1][0];
        else if ( strcmp ( ras1, s2 ) <= 0 )
            dp[i][0] += dp[i-1][1];
        else
            dp[i][0] = -1;

        /// dp[i][1]
        if ( strcmp ( s1, ras2 ) <= 0 )
            dp[i][1] += dp[i-1][0] + c[i];
        else if ( strcmp ( ras1, ras2 ) <= 0 )
            dp[i][1] += dp[i-1][1] + c[i];
        else
            dp[i][1] = -1;

        memset ( s1, 0, sizeof ( s2 ) );
        memset ( ras1, 0, sizeof ( ras2 ) );
        strcpy ( s1, s2 );
        strcpy ( ras1, ras2 );
        memset ( ras2, 0, sizeof ( ras2 ) );
        memset ( ras2, 0, sizeof ( ras2 ) );
    }
    printf ( "%d", min ( dp[n][0], dp[n][1] ) );
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
const int NMAX = 100000;
using namespace std;
long long dp[NMAX+5][5];
int c[NMAX+5];
char s1[NMAX+5], s2[NMAX+5];
inline int cmp1 ( char r1[], char s[] ) {
    int n1, n2, i;
    n1 = strlen ( r1 );
    n2 = strlen ( s );
    if ( n1 > n2 )
        return 1;
    else if ( n1 < n2 )
        return -1;
    n1--;
    i = 0;
    while ( r1[n1] == s[i] && n1 >= 0 ) {
        i++;
        n1--;
    }
    if ( n1 < 0 )
        return 0;
    else if ( r1[n1] > s[i] )
        return 1;
    return -1;
}
inline int cmp2 ( char r1[], char r2[] ) {
    int n1, n2;
    n1 = strlen ( r1 );
    n2 = strlen ( r2 );
    if ( n1 > n2 )
        return 1;
    else if ( n1 < n2 )
        return -1;
    n1--;
    n2--;
    while ( r1[n1] == r2[n2] && n1 >= 0 ) {
        n2--;
        n1--;
    }
    if ( n1 < 0 )
        return 0;
    else if ( r1[n1] > r2[n2] )
        return 1;
    return -1;
}
inline int cmp3 ( char a1[], char a2[] ) {
    int n1, n2, i, j;
    n1 = strlen ( a1 );
    n2 = strlen ( a2 );
    if ( n1 > n2 )
        return 1;
    else if ( n1 < n2 )
        return -1;
    i = j = 0;
    while ( a1[i] == a2[j] && i < n1 ) {
        i++;
        j++;
    }
    if ( i == n1 )
        return 0;
    else if ( a1[i] > a2[j] )
        return 1;
    return -1;
}
int main() {
    freopen ( "hard.in", "r", stdin );
    freopen ( "hard.out", "w", stdout );
    int n, i, j, k, n1, n2;
    scanf ( "%d", &n );
    for ( i = 1 ; i <= n ;  ++ i )
        scanf ( "%d", &c[i] );
    getc ( stdin );
    gets ( s1 );
    n1 = strlen ( s1 );
    dp[1][0] = 0;
    dp[1][1] = c[1];
    for ( i = 2 ; i <= n ; ++ i ) {

        gets ( s2 );

        /// dp[i][0]
        if ( cmp3 ( s1, s2 ) < 0 && dp[i-1][0] != -1 )
            dp[i][0] += dp[i-1][0];
        else if ( cmp1 ( s1, s2 ) < 0 && dp[i-1][1] != -1 )
            dp[i][0] += dp[i-1][1];
        else
            dp[i][0] = -1;

        /// dp[i][1]
        if ( cmp1 ( s2, s1 ) > 0 && dp[i-1][0] != -1 )
            dp[i][1] += dp[i-1][0] + c[i];
        else if ( cmp2 ( s1, s2 ) < 0 && dp[i-1][1] != -1 )
            dp[i][1] += dp[i-1][1] + c[i];
        else
            dp[i][1] = -1;

        memset ( s1, 0, sizeof ( s2 ) );
        strcpy ( s1, s2 );
        memset ( s2, 0, sizeof ( s2 ) );
    }
    if ( dp[n][0] == -1 ) {
        if ( dp[n][1] == -1 )
            printf ( "-1" );
        else
            printf ( "%I64d", dp[n][1] );
    }
    else if ( dp[n][1] == -1 )
        printf ( "%I64d", dp[n][0] );
    else
        printf ( "%I64d", min ( dp[n][0], dp[n][1] ) );
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
const int NMAX = 100000;
using namespace std;
long long dp[NMAX+5][5];
int c[NMAX+5];
char s1[NMAX+5], s2[NMAX+5];
inline int cmp1 ( char r1[], char s[] ) {
    int n1, n2, i;
    n1 = strlen ( r1 );
    n2 = strlen ( s );
    n1--;
    i = 0;
    while ( r1[n1] == s[i] && n1 >= 0 && i < n2 ) {
        i++;
        n1--;
    }
    if ( n1 < 0 && i == n2 )
        return 0;
    else if ( n1 < 0 )
        return -1;
    else if ( i == n2 )
        return 1;
    else if ( r1[n1] > s[i] )
        return 1;
    return -1;
}
inline int cmp2 ( char r1[], char r2[] ) {
    int n1, n2;
    n1 = strlen ( r1 );
    n2 = strlen ( r2 );
    n1--;
    n2--;
    while ( r1[n1] == r2[n2] && n1 >= 0 && n2 >= 0 ) {
        n2--;
        n1--;
    }
    if ( n1 < 0 && n2 < 0 )
        return 0;
    if ( n1 < 0 )
        return -1;
    else if ( n2 < 0 )
        return 1;
    else if ( r1[n1] > r2[n2] )
        return 1;
    return -1;
}
inline int cmp3 ( char a1[], char a2[] ) {
    int n1, n2, i, j;
    n1 = strlen ( a1 );
    n2 = strlen ( a2 );
    i = j = 0;
    while ( a1[i] == a2[j] && i < n1 && j < n2 ) {
        i++;
        j++;
    }
    if ( i == n1 && j == n2 )
        return 0;
    else if ( i == n1 )
        return -1;
    else if ( j == n2 )
        return 1;
    else if ( a1[i] > a2[j] )
        return 1;
    return -1;
}
int main() {
    //freopen ( "hard.in", "r", stdin );
    //freopen ( "hard.out", "w", stdout );
    int n, i, j, k, n1, n2;
    scanf ( "%d", &n );
    for ( i = 1 ; i <= n ;  ++ i )
        scanf ( "%d", &c[i] );
    getc ( stdin );
    gets ( s1 );
    n1 = strlen ( s1 );
    dp[1][0] = 0;
    dp[1][1] = c[1];
    for ( i = 2 ; i <= n ; ++ i ) {

        gets ( s2 );

        /// dp[i][0]
        if ( cmp3 ( s1, s2 ) <= 0 && dp[i-1][0] != -1 )
            dp[i][0] += dp[i-1][0];
        else if ( cmp1 ( s1, s2 ) <= 0 && dp[i-1][1] != -1 )
            dp[i][0] += dp[i-1][1];
        else
            dp[i][0] = -1;

        /// dp[i][1]
        if ( cmp1 ( s2, s1 ) >= 0 && dp[i-1][0] != -1 )
            dp[i][1] += dp[i-1][0] + c[i];
        else if ( cmp2 ( s1, s2 ) <= 0 && dp[i-1][1] != -1 )
            dp[i][1] += dp[i-1][1] + c[i];
        else
            dp[i][1] = -1;

        memset ( s1, 0, sizeof ( s2 ) );
        strcpy ( s1, s2 );
        memset ( s2, 0, sizeof ( s2 ) );
    }
    if ( dp[n][0] == -1 ) {
        if ( dp[n][1] == -1 )
            printf ( "-1\n" );
        else
            printf ( "%I64d\n", dp[n][1] );
    }
    else if ( dp[n][1] == -1 )
        printf ( "%I64d\n", dp[n][0] );
    else
        printf ( "%I64d\n", min ( dp[n][0], dp[n][1] ) );
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
const int NMAX = 100000;
using namespace std;
long long dp[NMAX+5][5];
int c[NMAX+5];
char s1[NMAX+5], s2[NMAX+5];
inline int cmp1 ( char r1[], char s[] ) {
    int n1, n2, i;
    n1 = strlen ( r1 );
    n2 = strlen ( s );
    if ( n1 > n2 )
        return 1;
    else if ( n1 < n2 )
        return -1;
    n1--;
    i = 0;
    while ( r1[n1] == s[i] && n1 >= 0 ) {
        i++;
        n1--;
    }
    if ( n1 < 0 )
        return 0;
    else if ( r1[n1] > s[i] )
        return 1;
    return -1;
}
inline int cmp2 ( char r1[], char r2[] ) {
    int n1, n2;
    n1 = strlen ( r1 );
    n2 = strlen ( r2 );
    if ( n1 > n2 )
        return 1;
    else if ( n1 < n2 )
        return -1;
    n1--;
    n2--;
    while ( r1[n1] == r2[n2] && n1 >= 0 ) {
        n2--;
        n1--;
    }
    if ( n1 < 0 )
        return 0;
    else if ( r1[n1] > r2[n2] )
        return 1;
    return -1;
}
inline int cmp3 ( char a1[], char a2[] ) {
    int n1, n2, i, j;
    n1 = strlen ( a1 );
    n2 = strlen ( a2 );
    if ( n1 > n2 )
        return 1;
    else if ( n1 < n2 )
        return -1;
    i = j = 0;
    while ( a1[i] == a2[j] && i < n1 ) {
        i++;
        j++;
    }
    if ( i == n1 )
        return 0;
    else if ( a1[i] > a2[j] )
        return 1;
    return -1;
}
int main() {
    //freopen ( "hard.in", "r", stdin );
    //freopen ( "hard.out", "w", stdout );
    int n, i, j, k, n1, n2;
    scanf ( "%d", &n );
    for ( i = 1 ; i <= n ;  ++ i )
        scanf ( "%d", &c[i] );
    getc ( stdin );
    gets ( s1 );
    n1 = strlen ( s1 );
    dp[1][0] = 0;
    dp[1][1] = c[1];
    for ( i = 2 ; i <= n ; ++ i ) {

        gets ( s2 );

        /// dp[i][0]
        if ( cmp3 ( s1, s2 ) <= 0 && dp[i-1][0] != -1 )
            dp[i][0] += dp[i-1][0];
        else if ( cmp1 ( s1, s2 ) <= 0 && dp[i-1][1] != -1 )
            dp[i][0] += dp[i-1][1];
        else
            dp[i][0] = -1;

        /// dp[i][1]
        if ( cmp1 ( s2, s1 ) >= 0 && dp[i-1][0] != -1 )
            dp[i][1] += dp[i-1][0] + c[i];
        else if ( cmp2 ( s1, s2 ) <= 0 && dp[i-1][1] != -1 )
            dp[i][1] += dp[i-1][1] + c[i];
        else
            dp[i][1] = -1;

        memset ( s1, 0, sizeof ( s2 ) );
        strcpy ( s1, s2 );
        memset ( s2, 0, sizeof ( s2 ) );
    }
    if ( dp[n][0] == -1 ) {
        if ( dp[n][1] == -1 )
            printf ( "-1" );
        else
            printf ( "%I64d", dp[n][1] );
    }
    else if ( dp[n][1] == -1 )
        printf ( "%I64d", dp[n][0] );
    else
        printf ( "%I64d", min ( dp[n][0], dp[n][1] ) );
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
const int NMAX = 100000;
using namespace std;
long long dp[NMAX+5][5];
int c[NMAX+5];
char s1[NMAX+5], s2[NMAX+5];
inline int cmp1 ( char r1[], char s[] ) {
    int n1, n2, i;
    n1 = strlen ( r1 );
    n2 = strlen ( s );
    n1--;
    i = 0;
    while ( r1[n1] == s[i] && n1 >= 0 && i < n2 ) {
        i++;
        n1--;
    }
    if ( n1 < 0 && i == n2 )
        return 0;
    else if ( n1 < 0 )
        return -1;
    else if ( i == n2 )
        return 1;
    else if ( r1[n1] > s[i] )
        return 1;
    return -1;
}
inline int cmp2 ( char r1[], char r2[] ) {
    int n1, n2;
    n1 = strlen ( r1 );
    n2 = strlen ( r2 );
    n1--;
    n2--;
    while ( r1[n1] == r2[n2] && n1 >= 0 && n2 >= 0 ) {
        n2--;
        n1--;
    }
    if ( n1 < 0 && n2 < 0 )
        return 0;
    if ( n1 < 0 )
        return -1;
    else if ( n2 < 0 )
        return 1;
    else if ( r1[n1] > r2[n2] )
        return 1;
    return -1;
}
inline int cmp3 ( char a1[], char a2[] ) {
    int n1, n2, i, j;
    n1 = strlen ( a1 );
    n2 = strlen ( a2 );
    i = j = 0;
    while ( a1[i] == a2[j] && i < n1 && j < n2 ) {
        i++;
        j++;
    }
    if ( i == n1 && j == n2 )
        return 0;
    else if ( i == n1 )
        return -1;
    else if ( j == n2 )
        return 1;
    else if ( a1[i] > a2[j] )
        return 1;
    return -1;
}
int main() {
    int n, i, j, k, n1, n2;
    scanf ( "%d", &n );
    for ( i = 1 ; i <= n ;  ++ i )
        scanf ( "%d", &c[i] );
    getc ( stdin );
    gets ( s1 );
    n1 = strlen ( s1 );
    dp[1][0] = 0;
    dp[1][1] = c[1];
    for ( i = 2 ; i <= n ; ++ i ) {

        gets ( s2 );

        /// dp[i][0]
        if ( cmp3 ( s1, s2 ) < 0 && dp[i-1][0] != -1 )
            dp[i][0] += dp[i-1][0];
        else if ( cmp1 ( s1, s2 ) < 0 && dp[i-1][1] != -1 )
            dp[i][0] += dp[i-1][1];
        else
            dp[i][0] = -1;

        /// dp[i][1]
        if ( cmp1 ( s2, s1 ) > 0 && dp[i-1][0] != -1 )
            dp[i][1] += dp[i-1][0] + c[i];
        else if ( cmp2 ( s1, s2 ) < 0 && dp[i-1][1] != -1 )
            dp[i][1] += dp[i-1][1] + c[i];
        else
            dp[i][1] = -1;

        memset ( s1, 0, sizeof ( s2 ) );
        strcpy ( s1, s2 );
        memset ( s2, 0, sizeof ( s2 ) );
    }
    if ( dp[n][0] == -1 ) {
        if ( dp[n][1] == -1 )
            printf ( "-1\n" );
        else
            printf ( "%I64d\n", dp[n][1] );
    }
    else if ( dp[n][1] == -1 )
        printf ( "%I64d\n", dp[n][0] );
    else
        printf ( "%I64d\n", min ( dp[n][0], dp[n][1] ) );
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
const int NMAX = 100000;
using namespace std;
int dp[NMAX+5][5];
int c[NMAX+5];
char s1[NMAX+5], s2[NMAX+5];
char ras1[NMAX+5], ras2[NMAX+5];
int main() {
    //freopen ( "hard.in", "r", stdin );
    //freopen ( "hard.out", "w", stdout );
    int n, i, j, k, n1, n2;
    scanf ( "%d", &n );
    for ( i = 1 ; i <= n ;  ++ i )
        scanf ( "%d", &c[i] );
    getc ( stdin );
    gets ( s1 );
    n1 = strlen ( s1 );
    j = n1;
    for ( i = 0 ; i < n1 ; ++ i )
        ras1[i] = s1[--j];
    dp[1][0] = 0;
    dp[1][1] = c[1];
    for ( i = 2 ; i <= n ; ++ i ) {

        gets ( s2 );
        n2 = strlen ( s2 );
        k = n2;
        for ( j = 0 ; j < n2 ; ++ j )
            ras2[j] = s2[--k];

        /// dp[i][0]
        if ( strcmp ( s1, s2 ) <= 0 )
            dp[i][0] += dp[i-1][0];
        else if ( strcmp ( ras1, s2 ) <= 0 )
            dp[i][0] += dp[i-1][1];
        else
            dp[i][0] = -1;

        /// dp[i][1]
        if ( strcmp ( s1, ras2 ) <= 0 )
            dp[i][1] += dp[i-1][0] + c[i];
        else if ( strcmp ( ras1, ras2 ) <= 0 )
            dp[i][1] += dp[i-1][1] + c[i];
        else
            dp[i][1] = -1;

        memset ( s1, 0, sizeof ( s2 ) );
        memset ( ras1, 0, sizeof ( ras2 ) );
        strcpy ( s1, s2 );
        strcpy ( ras1, ras2 );
        memset ( ras2, 0, sizeof ( ras2 ) );
        memset ( s2, 0, sizeof ( s2 ) );
    }
    if ( dp[n][0] == -1 ) {
        if ( dp[n][1] == -1 )
            printf ( "-1" );
        else
            printf ( "%d", dp[n][1] );
    }
    else if ( dp[n][1] == -1 )
        printf ( "%d", dp[n][0] );
    else
        printf ( "%d", min ( dp[n][0], dp[n][1] ) );
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
const int NMAX = 100000;
using namespace std;
long long dp[NMAX+5][5];
int c[NMAX+5];
char s1[NMAX+5], s2[NMAX+5];
inline int cmp1 ( char r1[], char s[] ) {
    int n1, n2, i;
    n1 = strlen ( r1 );
    n2 = strlen ( s );
    if ( n1 > n2 )
        return 1;
    else if ( n1 < n2 )
        return -1;
    n1--;
    i = 0;
    while ( r1[n1] == s[i] && n1 >= 0 ) {
        i++;
        n1--;
    }
    if ( n1 < 0 )
        return 0;
    else if ( r1[n1] > s[i] )
        return 1;
    return -1;
}
inline int cmp2 ( char r1[], char r2[] ) {
    int n1, n2;
    n1 = strlen ( r1 );
    n2 = strlen ( r2 );
    if ( n1 > n2 )
        return 1;
    else if ( n1 < n2 )
        return -1;
    n1--;
    n2--;
    while ( r1[n1] == r2[n2] && n1 >= 0 ) {
        n2--;
        n1--;
    }
    if ( n1 < 0 )
        return 0;
    else if ( r1[n1] > r2[n2] )
        return 1;
    return -1;
}
inline int cmp3 ( char a1[], char a2[] ) {
    int n1, n2, i, j;
    n1 = strlen ( a1 );
    n2 = strlen ( a2 );
    if ( n1 > n2 )
        return 1;
    else if ( n1 < n2 )
        return -1;
    i = j = 0;
    while ( a1[i] == a2[j] && i < n1 ) {
        i++;
        j++;
    }
    if ( i == n1 )
        return 0;
    else if ( a1[i] > a2[j] )
        return 1;
    return -1;
}
int main() {
    //freopen ( "hard.in", "r", stdin );
    //freopen ( "hard.out", "w", stdout );
    int n, i, j, k, n1, n2;
    scanf ( "%d", &n );
    for ( i = 1 ; i <= n ;  ++ i )
        scanf ( "%d", &c[i] );
    getc ( stdin );
    gets ( s1 );
    n1 = strlen ( s1 );
    dp[1][0] = 0;
    dp[1][1] = c[1];
    for ( i = 2 ; i <= n ; ++ i ) {

        gets ( s2 );

        /// dp[i][0]
        if ( cmp3 ( s1, s2 ) < 0 && dp[i-1][0] != -1 )
            dp[i][0] += dp[i-1][0];
        else if ( cmp1 ( s1, s2 ) < 0 && dp[i-1][1] != -1 )
            dp[i][0] += dp[i-1][1];
        else
            dp[i][0] = -1;

        /// dp[i][1]
        if ( cmp1 ( s2, s1 ) > 0 && dp[i-1][0] != -1 )
            dp[i][1] += dp[i-1][0] + c[i];
        else if ( cmp2 ( s1, s2 ) < 0 && dp[i-1][1] != -1 )
            dp[i][1] += dp[i-1][1] + c[i];
        else
            dp[i][1] = -1;

        memset ( s1, 0, sizeof ( s2 ) );
        strcpy ( s1, s2 );
        memset ( s2, 0, sizeof ( s2 ) );
    }
    if ( dp[n][0] == -1 ) {
        if ( dp[n][1] == -1 )
            printf ( "-1" );
        else
            printf ( "%I64d", dp[n][1] );
    }
    else if ( dp[n][1] == -1 )
        printf ( "%I64d", dp[n][0] );
    else
        printf ( "%I64d", min ( dp[n][0], dp[n][1] ) );
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
const int NMAX = 100000;
using namespace std;
long long dp[NMAX+5][5];
int c[NMAX+5];
char s1[NMAX+5], s2[NMAX+5];
char ras1[NMAX+5], ras2[NMAX+5];
int main() {
    //freopen ( "hard.in", "r", stdin );
    //freopen ( "hard.out", "w", stdout );
    int n, i, j, k, n1, n2;
    scanf ( "%d", &n );
    for ( i = 1 ; i <= n ;  ++ i )
        scanf ( "%d", &c[i] );
    getc ( stdin );
    gets ( s1 );
    n1 = strlen ( s1 );
    j = n1;
    for ( i = 0 ; i < n1 ; ++ i )
        ras1[i] = s1[--j];
    dp[1][0] = 0;
    dp[1][1] = c[1];
    for ( i = 2 ; i <= n ; ++ i ) {

        gets ( s2 );
        n2 = strlen ( s2 );
        k = n2;
        for ( j = 0 ; j < n2 ; ++ j )
            ras2[j] = s2[--k];

        /// dp[i][0]
        if ( strcmp ( s1, s2 ) <= 0 && dp[i-1][0] != -1 )
            dp[i][0] += dp[i-1][0];
        else if ( strcmp ( ras1, s2 ) <= 0 && dp[i-1][1] != -1 )
            dp[i][0] += dp[i-1][1];
        else
            dp[i][0] = -1;

        /// dp[i][1]
        if ( strcmp ( s1, ras2 ) <= 0 && dp[i-1][0] != -1 )
            dp[i][1] += dp[i-1][0] + c[i];
        else if ( strcmp ( ras1, ras2 ) <= 0 && dp[i-1][1] != -1 )
            dp[i][1] += dp[i-1][1] + c[i];
        else
            dp[i][1] = -1;

        memset ( s1, 0, sizeof ( s2 ) );
        memset ( ras1, 0, sizeof ( ras2 ) );
        strcpy ( s1, s2 );
        strcpy ( ras1, ras2 );
        memset ( ras2, 0, sizeof ( ras2 ) );
        memset ( s2, 0, sizeof ( s2 ) );
    }
    if ( dp[n][0] == -1 ) {
        if ( dp[n][1] == -1 )
            printf ( "-1" );
        else
            printf ( "%lld", dp[n][1] );
    }
    else if ( dp[n][1] == -1 )
        printf ( "%I64d", dp[n][0] );
    else
        printf ( "%I64d", min ( dp[n][0], dp[n][1] ) );
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
const int NMAX = 100000;
using namespace std;
long long dp[NMAX+5][5];
int c[NMAX+5];
char s1[NMAX+5], s2[NMAX+5];
inline int cmp1 ( char r1[], char s[] ) {
    int n1, n2, i;
    n1 = strlen ( r1 );
    n2 = strlen ( s );
    n1--;
    i = 0;
    while ( r1[n1] == s[i] && n1 >= 0 && i < n2 ) {
        i++;
        n1--;
    }
    if ( n1 < 0 && i == n2 )
        return 0;
    else if ( n1 < 0 )
        return -1;
    else if ( i == n2 )
        return 1;
    else if ( r1[n1] > s[i] )
        return 1;
    return -1;
}
inline int cmp2 ( char r1[], char r2[] ) {
    int n1, n2;
    n1 = strlen ( r1 );
    n2 = strlen ( r2 );
    n1--;
    n2--;
    while ( r1[n1] == r2[n2] && n1 >= 0 && n2 >= 0 ) {
        n2--;
        n1--;
    }
    if ( n1 < 0 && n2 < 0 )
        return 0;
    if ( n1 < 0 )
        return -1;
    else if ( n2 < 0 )
        return 1;
    else if ( r1[n1] > r2[n2] )
        return 1;
    return -1;
}
inline int cmp3 ( char a1[], char a2[] ) {
    int n1, n2, i, j;
    n1 = strlen ( a1 );
    n2 = strlen ( a2 );
    i = j = 0;
    while ( a1[i] == a2[j] && i < n1 && j < n2 ) {
        i++;
        j++;
    }
    if ( i == n1 && j == n2 )
        return 0;
    else if ( i == n1 )
        return -1;
    else if ( j == n2 )
        return 1;
    else if ( a1[i] > a2[j] )
        return 1;
    return -1;
}
int main() {
    int n, i, j, k, n1, n2;
    scanf ( "%d", &n );
    for ( i = 1 ; i <= n ;  ++ i )
        scanf ( "%d", &c[i] );
    getc ( stdin );
    gets ( s1 );
    n1 = strlen ( s1 );
    dp[1][0] = 0;
    dp[1][1] = c[1];
    for ( i = 2 ; i <= n ; ++ i ) {

        gets ( s2 );

        /// dp[i][0]
        if ( cmp3 ( s1, s2 ) <= 0 && dp[i-1][0] != -1 )
            dp[i][0] += dp[i-1][0];
        else if ( cmp1 ( s1, s2 ) <= 0 && dp[i-1][1] != -1 )
            dp[i][0] += dp[i-1][1];
        else
            dp[i][0] = -1;

        /// dp[i][1]
        if ( cmp1 ( s2, s1 ) >= 0 && dp[i-1][0] != -1 )
            dp[i][1] += dp[i-1][0] + c[i];
        else if ( cmp2 ( s1, s2 ) <= 0 && dp[i-1][1] != -1 )
            dp[i][1] += dp[i-1][1] + c[i];
        else
            dp[i][1] = -1;

        memset ( s1, 0, sizeof ( s2 ) );
        strcpy ( s1, s2 );
        memset ( s2, 0, sizeof ( s2 ) );
    }
    if ( dp[n][0] == -1 ) {
        if ( dp[n][1] == -1 )
            printf ( "-1" );
        else
            printf ( "%I64d", dp[n][1] );
    }
    else if ( dp[n][1] == -1 )
        printf ( "%I64d", dp[n][0] );
    else
        printf ( "%I64d", min ( dp[n][0], dp[n][1] ) );
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
const int NMAX = 100000;
using namespace std;
long long dp[NMAX+5][5];
int c[NMAX+5];
char s1[NMAX+5], s2[NMAX+5];
inline int cmp1 ( char r1[], char s[] ) {
    int n1, n2, i;
    n1 = strlen ( r1 );
    n2 = strlen ( s );
    n1--;
    i = 0;
    while ( r1[n1] == s[i] && n1 >= 0 && i < n2 ) {
        i++;
        n1--;
    }
    if ( n1 < 0 && i == n2 )
        return 0;
    else if ( n1 < 0 )
        return -1;
    else if ( i == n2 )
        return 1;
    else if ( r1[n1] > s[i] )
        return 1;
    return -1;
}
inline int cmp2 ( char r1[], char r2[] ) {
    int n1, n2;
    n1 = strlen ( r1 );
    n2 = strlen ( r2 );
    n1--;
    n2--;
    while ( r1[n1] == r2[n2] && n1 >= 0 && n2 >= 0 ) {
        n2--;
        n1--;
    }
    if ( n1 < 0 && n2 < 0 )
        return 0;
    if ( n1 < 0 )
        return -1;
    else if ( n2 < 0 )
        return 1;
    else if ( r1[n1] > r2[n2] )
        return 1;
    return -1;
}
inline int cmp3 ( char a1[], char a2[] ) {
    int n1, n2, i, j;
    n1 = strlen ( a1 );
    n2 = strlen ( a2 );
    i = j = 0;
    while ( a1[i] == a2[j] && i < n1 && j < n2 ) {
        i++;
        j++;
    }
    if ( i == n1 && j == n2 )
        return 0;
    else if ( i == n1 )
        return -1;
    else if ( j == n2 )
        return 1;
    else if ( a1[i] > a2[j] )
        return 1;
    return -1;
}
int main() {
    int n, i, j, k, n1, n2;
    scanf ( "%d", &n );
    for ( i = 1 ; i <= n ;  ++ i )
        scanf ( "%d", &c[i] );
    getc ( stdin );
    gets ( s1 );
    n1 = strlen ( s1 );
    dp[1][0] = 0;
    dp[1][1] = c[1];
    for ( i = 2 ; i <= n ; ++ i ) {

        gets ( s2 );

        /// dp[i][0]
        if ( cmp3 ( s1, s2 ) <= 0 && dp[i-1][0] != -1 )
            dp[i][0] += dp[i-1][0];
        else if ( cmp1 ( s1, s2 ) <= 0 && dp[i-1][1] != -1 )
            dp[i][0] += dp[i-1][1];
        else
            dp[i][0] = -1;

        /// dp[i][1]
        if ( cmp1 ( s2, s1 ) >= 0 && dp[i-1][0] != -1 )
            dp[i][1] += dp[i-1][0] + c[i];
        else if ( cmp2 ( s1, s2 ) <= 0 && dp[i-1][1] != -1 )
            dp[i][1] += dp[i-1][1] + c[i];
        else
            dp[i][1] = -1;

        memset ( s1, 0, sizeof ( s2 ) );
        strcpy ( s1, s2 );
        memset ( s2, 0, sizeof ( s2 ) );
    }
    if ( dp[n][0] == -1 ) {
        if ( dp[n][1] == -1 )
            printf ( "-1\n" );
        else
            printf ( "%I64d\n", dp[n][1] );
    }
    else if ( dp[n][1] == -1 )
        printf ( "%I64d\n", dp[n][0] );
    else
        printf ( "%I64d\n", min ( dp[n][0], dp[n][1] ) );
    return 0;
}


#include <cstdio>
#include <cstring>
const int NMAX = 100000;
using namespace std;
long long dp[NMAX+5][5];
int c[NMAX+5];
char s1[NMAX+5], s2[NMAX+5];
inline int cmp1 ( char r1[], char s[] ) {
    int n1, n2, i;
    n1 = strlen ( r1 );
    n2 = strlen ( s );
    n1--;
    i = 0;
    while ( r1[n1] == s[i] && n1 >= 0 && i < n2 ) {
        i++;
        n1--;
    }
    if ( n1 < 0 && i == n2 )
        return 0;
    else if ( n1 < 0 )
        return -1;
    else if ( i == n2 )
        return 1;
    else if ( r1[n1] > s[i] )
        return 1;
    return -1;
}
inline int cmp2 ( char r1[], char r2[] ) {
    int n1, n2;
    n1 = strlen ( r1 );
    n2 = strlen ( r2 );
    n1--;
    n2--;
    while ( r1[n1] == r2[n2] && n1 >= 0 && n2 >= 0 ) {
        n2--;
        n1--;
    }
    if ( n1 < 0 && n2 < 0 )
        return 0;
    if ( n1 < 0 )
        return -1;
    else if ( n2 < 0 )
        return 1;
    else if ( r1[n1] > r2[n2] )
        return 1;
    return -1;
}
inline int cmp3 ( char a1[], char a2[] ) {
    int n1, n2, i, j;
    n1 = strlen ( a1 );
    n2 = strlen ( a2 );
    i = j = 0;
    while ( a1[i] == a2[j] && i < n1 && j < n2 ) {
        i++;
        j++;
    }
    if ( i == n1 && j == n2 )
        return 0;
    else if ( i == n1 )
        return -1;
    else if ( j == n2 )
        return 1;
    else if ( a1[i] > a2[j] )
        return 1;
    return -1;
}
int main() {
    int n, i, j, k, n1, n2;
    scanf ( "%d", &n );
    for ( i = 1 ; i <= n ;  ++ i )
        scanf ( "%d", &c[i] );
    getc ( stdin );
    gets ( s1 );
    n1 = strlen ( s1 );
    dp[1][0] = 0;
    dp[1][1] = c[1];
    for ( i = 2 ; i <= n ; ++ i ) {

        gets ( s2 );

        /// dp[i][0]
        if ( cmp3 ( s1, s2 ) <= 0 && dp[i-1][0] != -1 )
            dp[i][0] += dp[i-1][0];
        else if ( cmp1 ( s1, s2 ) <= 0 && dp[i-1][1] != -1 )
            dp[i][0] += dp[i-1][1];
        else
            dp[i][0] = -1;

        /// dp[i][1]
        if ( cmp1 ( s2, s1 ) >= 0 && dp[i-1][0] != -1 )
            dp[i][1] += 1LL * ( dp[i-1][0] + 1LL * c[i] );
        else if ( cmp2 ( s1, s2 ) <= 0 && dp[i-1][1] != -1 )
            dp[i][1] += 1LL * ( dp[i-1][1] + 1LL * c[i] );
        else
            dp[i][1] = -1;

        memset ( s1, 0, sizeof ( s2 ) );
        strcpy ( s1, s2 );
        memset ( s2, 0, sizeof ( s2 ) );
    }
    if ( dp[n][0] == -1 ) {
        if ( dp[n][1] == -1 )
            printf ( "-1\n" );
        else
            printf ( "%I64d\n", dp[n][1] );
    }
    else if ( dp[n][1] == -1 )
        printf ( "%I64d\n", dp[n][0] );
    else if ( dp[n][0] < dp[n][1] )
        printf ( "%I64d\n", dp[n][0] );
    else
        printf ( "%I64d\n", dp[n][1] );
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
const int NMAX = 100000;
using namespace std;
long long dp[NMAX+5][5];
int c[NMAX+5];
char s1[NMAX+5], s2[NMAX+5];
inline int cmp1 ( char r1[], char s[] ) {
    int n1, n2, i;
    n1 = strlen ( r1 );
    n2 = strlen ( s );
    if ( n1 > n2 )
        return 1;
    else if ( n1 < n2 )
        return -1;
    n1--;
    i = 0;
    while ( r1[n1] == s[i] && n1 >= 0 ) {
        i++;
        n1--;
    }
    if ( n1 < 0 )
        return 0;
    else if ( r1[n1] > s[i] )
        return 1;
    return -1;
}
inline int cmp2 ( char r1[], char r2[] ) {
    int n1, n2;
    n1 = strlen ( r1 );
    n2 = strlen ( r2 );
    if ( n1 > n2 )
        return 1;
    else if ( n1 < n2 )
        return -1;
    n1--;
    n2--;
    while ( r1[n1] == r2[n2] && n1 >= 0 ) {
        n2--;
        n1--;
    }
    if ( n1 < 0 )
        return 0;
    else if ( r1[n1] > r2[n2] )
        return 1;
    return -1;
}
inline int cmp3 ( char a1[], char a2[] ) {
    int n1, n2, i, j;
    n1 = strlen ( a1 );
    n2 = strlen ( a2 );
    if ( n1 > n2 )
        return 1;
    else if ( n1 < n2 )
        return -1;
    i = j = 0;
    while ( a1[i] == a2[j] && i < n1 ) {
        i++;
        j++;
    }
    if ( i == n1 )
        return 0;
    else if ( a1[i] > a2[j] )
        return 1;
    return -1;
}
int main() {
    int n, i, j, k, n1, n2;
    scanf ( "%d", &n );
    for ( i = 1 ; i <= n ;  ++ i )
        scanf ( "%d", &c[i] );
    getc ( stdin );
    gets ( s1 );
    n1 = strlen ( s1 );
    dp[1][0] = 0;
    dp[1][1] = c[1];
    for ( i = 2 ; i <= n ; ++ i ) {

        gets ( s2 );

        /// dp[i][0]
        if ( cmp3 ( s1, s2 ) <= 0 && dp[i-1][0] != -1 )
            dp[i][0] += dp[i-1][0];
        else if ( cmp1 ( s1, s2 ) <= 0 && dp[i-1][1] != -1 )
            dp[i][0] += dp[i-1][1];
        else
            dp[i][0] = -1;

        /// dp[i][1]
        if ( cmp1 ( s2, s1 ) >= 0 && dp[i-1][0] != -1 )
            dp[i][1] += dp[i-1][0] + c[i];
        else if ( cmp2 ( s1, s2 ) <= 0 && dp[i-1][1] != -1 )
            dp[i][1] += dp[i-1][1] + c[i];
        else
            dp[i][1] = -1;

        memset ( s1, 0, sizeof ( s2 ) );
        strcpy ( s1, s2 );
        memset ( s2, 0, sizeof ( s2 ) );
    }
    if ( dp[n][0] == -1 ) {
        if ( dp[n][1] == -1 )
            printf ( "-1" );
        else
            printf ( "%I64d", dp[n][1] );
    }
    else if ( dp[n][1] == -1 )
        printf ( "%I64d", dp[n][0] );
    else
        printf ( "%I64d", min ( dp[n][0], dp[n][1] ) );
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
bool isCorrect(string a,string b)
{
	// cout << a << " " << b << endl;
	if(a.compare(b)<0)
	{
		// cout << "true\n";
		return true;
	}
	else
	{
		// cout << "false\n";
		return false;
	}
}
bool checkRev(string a,string b)
{
	long long i=a.length()-1,j=0;
	// // cout << "a:::" << a << " b:::" << b << endl;
	while(i>=0 && j<b.length())
	{
		if(a[i]>b[j])
		{
			// // cout << "f\n";
			return false;
		}
		else if(a[i]<b[j])
		{
			// // cout << "t\n";
			return true;
		}
		i--;
		j++;
	}
	if(a.length()<=b.length())
		return true;
	return false;
}
int main()
{
	long long n;
	vector<long long>costs;
	vector<string>elements;
	long long i;
	cin >> n;
	for(i=0;i<n;i++)
	{
		long long elem;
		cin >> elem;
		costs.push_back(elem);
	}
	for(i=0;i<n;i++)
	{
		string s;
		cin >> s;
		elements.push_back(s);
	}
	long long tot=0,mint;
	for(i=0;i<n-1;i++)
	{
		if(!isCorrect(elements[i],elements[i+1]))
		{
			// cout << elements[i] << " and " << elements[i+1] << " inc\n";
			string s=elements[i+1];
			string s1=elements[i];
			mint=LONG_MAX;
			bool flag=false;
			if(checkRev(s1,s)==true)
			{
				flag=true;
				// cout << "flag true\n";
				mint=costs[i];
			}
			// cout << "check cost i\n";
			if(checkRev(s,s1)==false)
			{
				// cout << "here too\n";
				if(flag)
				{
					mint=(mint<costs[i+1])?mint:costs[i+1];
					// cout << "mint:" << mint << endl;
				}
				else
				{
					// cout << "minttt:" << mint << endl;
					mint=costs[i+1];
				}
				flag=true;
			}
			// cout << "done\n";
			if(checkRev(s1,s)==false && checkRev(s,s1)==true)
			{
				cout << -1 << endl;
				break;
			}
			tot+=mint;
		}
		// cout << tot << endl;
	}
	if(i==n-1)
		cout << tot << endl;
}


#include <bits/stdc++.h>
using namespace std;
bool isCorrect(string a,string b)
{
	// cout << a << " " << b << endl;
	if(a.compare(b)<0)
	{
		// cout << "true\n";
		return true;
	}
	else
	{
		// cout << "false\n";
		return false;
	}
}
bool checkRev(string a,string b)
{
	long long i=a.length()-1,j=0;
	// // cout << "a:::" << a << " b:::" << b << endl;
	while(i>=0 && j<b.length())
	{
		if(a[i]>b[j])
		{
			// // cout << "f\n";
			return false;
		}
		else if(a[i]<b[j])
		{
			// // cout << "t\n";
			return true;
		}
		i--;
		j++;
	}
	if(a.length()<b.length())
		return true;
	return false;
}
int main()
{
	long long n;
	vector<long long>costs;
	vector<string>elements;
	long long i;
	cin >> n;
	for(i=0;i<n;i++)
	{
		long long elem;
		cin >> elem;
		costs.push_back(elem);
	}
	// // cout << "costs pushes\n";
	for(i=0;i<n;i++)
	{
		string s;
		cin >> s;
		elements.push_back(s);
	}
	// // cout << "strings pushed\n";
	long long tot=0,mint;
	for(i=0;i<n-1;i++)
	{
		if(!isCorrect(elements[i],elements[i+1]))
		{
			// cout << elements[i] << " and " << elements[i+1] << " inc\n";
			string s=elements[i+1];
			string s1=elements[i];
			bool flag=false;
			// cout << s[s.length()-1] << " " << s1[0] << endl;
			// cout << "check cost i+1\n";
			if(checkRev(s1,s)==true)
			{
				flag=true;
				// cout << "flag true\n";
				mint=costs[i+1];
			}
			// cout << "check cost i\n";
			if(checkRev(s,s1)==false)
			{
				// cout << "here too\n";
				if(flag)
				{
					mint=(mint<costs[i])?mint:costs[i];
					// cout << "mint:" << mint << endl;
				}
				else
				{
					// cout << "minttt:" << mint << endl;
					mint=costs[i];
				}
				flag=true;
			}
			// cout << "done\n";
			if(!flag)
			{
				cout << -1 << endl;
				break;
			}
			tot+=mint;
		}
		// cout << tot << endl;
	}
	if(i==n-1)
		cout << tot << endl;
}


#include <bits/stdc++.h>
using namespace std;
const long long inf=0x3f3f3f3f3f3f3f3fll;
bool isCorrect(string a,string b)
{
	// cout << a << " " << b << endl;
	if(a.compare(b)<0)
	{
		// cout << "true\n";
		return true;
	}
	else
	{
		// cout << "false\n";
		return false;
	}
}
bool checkRev(string a,string b)
{
	long long i=a.length()-1,j=0;
	// // cout << "a:::" << a << " b:::" << b << endl;
	while(i>=0 && j<b.length())
	{
		if(a[i]>b[j])
		{
			// // cout << "f\n";
			return false;
		}
		else if(a[i]<b[j])
		{
			// // cout << "t\n";
			return true;
		}
		i--;
		j++;
	}
	if(a.length()<=b.length())
		return true;
	return false;
}
long long minimum(long long a,long long b)
{
	return (a<b)?a:b;
}
long long getRes(vector<string>&org,vector<string>&rev,vector<long long>&costs)
{
	// cout << LLONG_MAX << " " << LONG_MAX << endl;
	long long dp_table[org.size()][2];
	long long i;
	for(i=0;i<org.size();i++)
	{
		dp_table[i][0]=inf;
		dp_table[i][1]=inf;
	}
	dp_table[0][0]=0;
	dp_table[0][1]=costs[0];
	for(i=1;i<org.size();i++)
	{
		if(org[i]>=org[i-1])
			dp_table[i][0]=dp_table[i-1][0];
		if(org[i]>=rev[i-1])
			dp_table[i][0]=minimum(dp_table[i][0],dp_table[i-1][1]);
		if(rev[i]>=org[i-1])
			dp_table[i][1]=dp_table[i-1][0]+costs[i];
		if(rev[i]>=rev[i-1])
			dp_table[i][1]=minimum(dp_table[i][1],dp_table[i-1][1]+costs[i]);
	}
	// cout << dp_table[org.size()-1][0] << " " << dp_table[org.size()-1][1] << endl;
	long long r=minimum(dp_table[org.size()-1][0],dp_table[org.size()-1][1]);
	if(r==inf)
		return -1;
	return r;
}
int main()
{
	long long n;
	vector<long long>costs;
	vector<string>elements;
	vector<string>elements_rev;
	long long i;
	cin >> n;
	for(i=0;i<n;i++)
	{
		long long elem;
		cin >> elem;
		costs.push_back(elem);
	}
	for(i=0;i<n;i++)
	{
		string s,s_rev;
		cin >> s;
		s_rev=s;
		reverse(s_rev.begin(),s_rev.end());
		elements.push_back(s);
		elements_rev.push_back(s_rev);
	}
	// long long dp_res=getRes(elements,elements_rev,costs);
	// cout << dp_res << endl;
	long long tot=0,mint;
	for(i=0;i<n-1;i++)
	{
		if(!isCorrect(elements[i],elements[i+1]))
		{
			// cout << elements[i] << " and " << elements[i+1] << " inc\n";
			string s=elements[i+1];
			string s1=elements[i];
			string s_rev=s;
			reverse(s_rev.begin(),s_rev.end());
			string s1_rev=s1;
			reverse(s1_rev.begin(),s1_rev.end());
			mint=LONG_MAX;
			// cout << s << " " << s1 << " " << s_rev << " " << s1_rev << endl;
			bool flag=false;
			if(s1_rev<=s)
			{
				flag=true;
				// cout << "flag true\n";
				mint=costs[i];
			}
			// cout << "check cost i\n";

			if(s_rev>=s1)
			{
				// cout << "here too\n";
				if(flag)
				{
					mint=(mint<costs[i+1])?mint:costs[i+1];
					// cout << "mint:" << mint << endl;
				}
				else
				{
					// cout << "minttt:" << mint << endl;
					mint=costs[i+1];
				}
				flag=true;
			}
			if(!flags && 1_rev<=s_rev)
			{
				flag=true;
				mint=(mint<(costs[i]+costs[i+1]))?mint:costs[i]+costs[i+1];
			}
			// cout << "done\n";
			if(!flag)
			{
				cout << -1 << endl;
				break;
			}
			tot+=mint;
		}
		// cout << tot << endl;
	}
	if(i==n-1)
		cout << tot << endl;
}


#include <bits/stdc++.h>
using namespace std;
const long long inf=0x3f3f3f3f3f3f3f3fll;
bool isCorrect(string a,string b)
{
	// cout << a << " " << b << endl;
	if(a.compare(b)<0)
	{
		// cout << "true\n";
		return true;
	}
	else
	{
		// cout << "false\n";
		return false;
	}
}
bool checkRev(string a,string b)
{
	long long i=a.length()-1,j=0;
	// // cout << "a:::" << a << " b:::" << b << endl;
	while(i>=0 && j<b.length())
	{
		if(a[i]>b[j])
		{
			// // cout << "f\n";
			return false;
		}
		else if(a[i]<b[j])
		{
			// // cout << "t\n";
			return true;
		}
		i--;
		j++;
	}
	if(a.length()<=b.length())
		return true;
	return false;
}
long long minimum(long long a,long long b)
{
	return (a<b)?a:b;
}
long long getRes(vector<string>&org,vector<string>&rev,vector<long long>&costs)
{
	// cout << LLONG_MAX << " " << LONG_MAX << endl;
	long long dp_table[org.size()][2];
	long long i;
	for(i=0;i<org.size();i++)
	{
		dp_table[i][0]=inf;
		dp_table[i][1]=inf;
	}
	dp_table[0][0]=0;
	dp_table[0][1]=costs[0];
	for(i=1;i<org.size();i++)
	{
		if(org[i]>=org[i-1])
			dp_table[i][0]=dp_table[i-1][0];
		if(org[i]>=rev[i-1])
			dp_table[i][0]=minimum(dp_table[i][0],dp_table[i-1][1]);
		if(rev[i]>=org[i-1])
			dp_table[i][1]=dp_table[i-1][0]+costs[i];
		if(rev[i]>=rev[i-1])
			dp_table[i][1]=minimum(dp_table[i][1],dp_table[i-1][1]+costs[i]);
	}
	// cout << dp_table[org.size()-1][0] << " " << dp_table[org.size()-1][1] << endl;
	long long r=minimum(dp_table[org.size()-1][0],dp_table[org.size()-1][1]);
	if(r==inf)
		return -1;
	return r;
}
int main()
{
	long long n;
	vector<long long>costs;
	vector<string>elements;
	vector<string>elements_rev;
	long long i;
	cin >> n;
	for(i=0;i<n;i++)
	{
		long long elem;
		cin >> elem;
		costs.push_back(elem);
	}
	for(i=0;i<n;i++)
	{
		string s,s_rev;
		cin >> s;
		s_rev=s;
		reverse(s_rev.begin(),s_rev.end());
		elements.push_back(s);
		elements_rev.push_back(s_rev);
	}
	// long long dp_res=getRes(elements,elements_rev,costs);
	// cout << dp_res << endl;
	long long tot=0,mint;
	for(i=0;i<n-1;i++)
	{
		if(!isCorrect(elements[i],elements[i+1]))
		{
			// cout << elements[i] << " and " << elements[i+1] << " inc\n";
			string s=elements[i+1];
			string s1=elements[i];
			string s_rev=s;
			reverse(s_rev.begin(),s_rev.end());
			string s1_rev=s1;
			reverse(s1_rev.begin(),s1_rev.end());
			mint=LONG_MAX;
			// cout << s << " " << s1 << " " << s_rev << " " << s1_rev << endl;
			bool flag=false;
			if(s1_rev<=s)
			{
				flag=true;
				// cout << "flag true\n";
				mint=costs[i];
			}
			// cout << "check cost i\n";

			if(s_rev>=s1)
			{
				// cout << "here too\n";
				if(flag)
				{
					mint=(mint<costs[i+1])?mint:costs[i+1];
					// cout << "mint:" << mint << endl;
				}
				else
				{
					// cout << "minttt:" << mint << endl;
					mint=costs[i+1];
				}
				flag=true;
			}
			if(s1_rev<=s_rev)
			{
				flag=true;
				mint=(mint<(costs[i]+costs[i+1]))?mint:costs[i]+costs[i+1];
			}
			// cout << "done\n";
			if(!flag)
			{
				cout << -1 << endl;
				break;
			}
			tot+=mint;
		}
		// cout << tot << endl;
	}
	if(i==n-1)
		cout << tot << endl;
}


#include <bits/stdc++.h>
using namespace std;
bool isCorrect(string a,string b)
{
	// cout << a << " " << b << endl;
	if(a.compare(b)<0)
	{
		// cout << "true\n";
		return true;
	}
	else
	{
		// cout << "false\n";
		return false;
	}
}
bool checkRev(string a,string b)
{
	long long i=a.length()-1,j=0;
	// // cout << "a:::" << a << " b:::" << b << endl;
	while(i>=0 && j<b.length())
	{
		if(a[i]>b[j])
		{
			// // cout << "f\n";
			return false;
		}
		else if(a[i]<b[j])
		{
			// // cout << "t\n";
			return true;
		}
		i--;
		j++;
	}
	if(a.length()<=b.length())
		return true;
	return false;
}
long long minimum(long long a,long long b)
{
	return (a<b)?a:b;
}
long long getRes(vector<string>&org,vector<string>&rev,vector<long long>&costs)
{
	long long dp_table[org.size()][2];
	long long i;
	for(i=0;i<org.size();i++)
	{
		dp_table[i][0]=LONG_MAX;
		dp_table[i][1]=LONG_MAX;
	}
	dp_table[0][0]=0;
	dp_table[0][1]=costs[0];
	for(i=1;i<org.size();i++)
	{
		if(org[i]>=org[i-1])
			dp_table[i][0]=dp_table[i-1][0];
		if(org[i]>=rev[i-1])
			dp_table[i][0]=minimum(dp_table[i][0],dp_table[i-1][1]);
		if(rev[i]>=org[i-1])
			dp_table[i][1]=dp_table[i-1][0]+costs[i];
		if(rev[i]>=rev[i-1])
			dp_table[i][1]=minimum(dp_table[i][1],dp_table[i-1][1]+costs[i]);
	}
	// cout << dp_table[org.size()-1][0] << " " << dp_table[org.size()-1][1] << endl;
	long long r=minimum(dp_table[org.size()-1][0],dp_table[org.size()-1][1]);
	if(r==LONG_MAX)
		return -1;
	return r;
}
int main()
{
	long long n;
	vector<long long>costs;
	vector<string>elements;
	vector<string>elements_rev;
	long long i;
	cin >> n;
	for(i=0;i<n;i++)
	{
		long long elem;
		cin >> elem;
		costs.push_back(elem);
	}
	for(i=0;i<n;i++)
	{
		string s,s_rev;
		cin >> s;
		s_rev=s;
		reverse(s_rev.begin(),s_rev.end());
		elements.push_back(s);
		elements_rev.push_back(s_rev);
	}
	long long dp_res=getRes(elements,elements_rev,costs);
	cout << dp_res << endl;
	// long long tot=0,mint;
	// for(i=0;i<n-1;i++)
	// {
	// 	if(!isCorrect(elements[i],elements[i+1]))
	// 	{
	// 		// cout << elements[i] << " and " << elements[i+1] << " inc\n";
	// 		string s=elements[i+1];
	// 		string s1=elements[i];
	// 		string s_rev=s;
	// 		reverse(s_rev.begin(),s_rev.end());
	// 		string s1_rev=s1;
	// 		reverse(s1_rev.begin(),s1_rev.end());
	// 		mint=LONG_MAX;
	// 		bool flag=false;
	// 		if(isCorrect(s1_rev,s))
	// 		{
	// 			flag=true;
	// 			// cout << "flag true\n";
	// 			mint=costs[i];
	// 		}
	// 		// cout << "check cost i\n";

	// 		if(!isCorrect(s_rev,s1))
	// 		{
	// 			// cout << "here too\n";
	// 			if(flag)
	// 			{
	// 				mint=(mint<costs[i+1])?mint:costs[i+1];
	// 				// cout << "mint:" << mint << endl;
	// 			}
	// 			else
	// 			{
	// 				// cout << "minttt:" << mint << endl;
	// 				mint=costs[i+1];
	// 			}
	// 			flag=true;
	// 		}
	// 		// cout << "done\n";
	// 		if(checkRev(s1,s)==false && checkRev(s,s1)==true)
	// 		{
	// 			cout << -1 << endl;
	// 			break;
	// 		}
	// 		tot+=mint;
	// 	}
	// 	// cout << tot << endl;
	// }
	// if(i==n-1)
		// cout << tot << endl;
}


#include <bits/stdc++.h>
using namespace std;
const long long inf=0x3f3f3f3f3f3f3f3fll;
bool isCorrect(string a,string b)
{
	// cout << a << " " << b << endl;
	if(a.compare(b)<0)
	{
		// cout << "true\n";
		return true;
	}
	else
	{
		// cout << "false\n";
		return false;
	}
}
bool checkRev(string a,string b)
{
	long long i=a.length()-1,j=0;
	// // cout << "a:::" << a << " b:::" << b << endl;
	while(i>=0 && j<b.length())
	{
		if(a[i]>b[j])
		{
			// // cout << "f\n";
			return false;
		}
		else if(a[i]<b[j])
		{
			// // cout << "t\n";
			return true;
		}
		i--;
		j++;
	}
	if(a.length()<=b.length())
		return true;
	return false;
}
long long minimum(long long a,long long b)
{
	return (a<b)?a:b;
}
long long getRes(vector<string>&org,vector<string>&rev,vector<long long>&costs)
{
	// cout << LLONG_MAX << " " << LONG_MAX << endl;
	long long dp_table[org.size()][2];
	long long i;
	for(i=0;i<org.size();i++)
	{
		dp_table[i][0]=inf;
		dp_table[i][1]=inf;
	}
	dp_table[0][0]=0;
	dp_table[0][1]=costs[0];
	for(i=1;i<org.size();i++)
	{
		if(org[i]>=org[i-1])
			dp_table[i][0]=dp_table[i-1][0];
		if(org[i]>=rev[i-1])
			dp_table[i][0]=minimum(dp_table[i][0],dp_table[i-1][1]);
		if(rev[i]>=org[i-1])
			dp_table[i][1]=dp_table[i-1][0]+costs[i];
		if(rev[i]>=rev[i-1])
			dp_table[i][1]=minimum(dp_table[i][1],dp_table[i-1][1]+costs[i]);
	}
	// cout << dp_table[org.size()-1][0] << " " << dp_table[org.size()-1][1] << endl;
	long long r=minimum(dp_table[org.size()-1][0],dp_table[org.size()-1][1]);
	if(r==inf)
		return -1;
	return r;
}
int main()
{
	long long n;
	vector<long long>costs;
	vector<string>elements;
	vector<string>elements_rev;
	long long i;
	cin >> n;
	for(i=0;i<n;i++)
	{
		long long elem;
		cin >> elem;
		costs.push_back(elem);
	}
	for(i=0;i<n;i++)
	{
		string s,s_rev;
		cin >> s;
		s_rev=s;
		reverse(s_rev.begin(),s_rev.end());
		elements.push_back(s);
		elements_rev.push_back(s_rev);
	}
	// long long dp_res=getRes(elements,elements_rev,costs);
	// cout << dp_res << endl;
	long long tot=0,mint;
	for(i=0;i<n-1;i++)
	{
		if(!isCorrect(elements[i],elements[i+1]))
		{
			// cout << elements[i] << " and " << elements[i+1] << " inc\n";
			string s=elements[i+1];
			string s1=elements[i];
			string s_rev=s;
			reverse(s_rev.begin(),s_rev.end());
			string s1_rev=s1;
			reverse(s1_rev.begin(),s1_rev.end());
			mint=LONG_MAX;
			// cout << s << " " << s1 << " " << s_rev << " " << s1_rev << endl;
			bool flag=false;
			if(s1_rev<=s)
			{
				flag=true;
				// cout << "flag true\n";
				mint=costs[i];
			}
			// cout << "check cost i\n";

			if(s_rev>=s1)
			{
				// cout << "here too\n";
				if(flag)
				{
					mint=(mint<costs[i+1])?mint:costs[i+1];
					// cout << "mint:" << mint << endl;
				}
				else
				{
					// cout << "minttt:" << mint << endl;
					mint=costs[i+1];
				}
				flag=true;
			}
			if(!flag && s1_rev<=s_rev)
			{
				flag=true;
				mint=(mint<(costs[i]+costs[i+1]))?mint:costs[i]+costs[i+1];
			}
			// cout << "done\n";
			if(!flag)
			{
				cout << -1 << endl;
				break;
			}
			tot+=mint;
		}
		// cout << tot << endl;
	}
	if(i==n-1)
		cout << tot << endl;
}


#include <bits/stdc++.h>
using namespace std;
bool isCorrect(string a,string b)
{
	// cout << a << " " << b << endl;
	if(a.compare(b)<0)
	{
		// cout << "true\n";
		return true;
	}
	else
	{
		// cout << "false\n";
		return false;
	}
}
bool checkRev(string a,string b)
{
	long long i=a.length()-1,j=0;
	// // cout << "a:::" << a << " b:::" << b << endl;
	while(i>=0 && j<b.length())
	{
		if(a[i]>b[j])
		{
			// // cout << "f\n";
			return false;
		}
		else if(a[i]<b[j])
		{
			// // cout << "t\n";
			return true;
		}
		i--;
		j++;
	}
	if(a.length()<b.length())
		return true;
	return false;
}
int main()
{
	long long n;
	vector<long long>costs;
	vector<string>elements;
	long long i;
	cin >> n;
	for(i=0;i<n;i++)
	{
		long long elem;
		cin >> elem;
		costs.push_back(elem);
	}
	// // cout << "costs pushes\n";
	for(i=0;i<n;i++)
	{
		string s;
		cin >> s;
		elements.push_back(s);
	}
	// // cout << "strings pushed\n";
	long long tot=0,mint;
	for(i=0;i<n-1;i++)
	{
		if(!isCorrect(elements[i],elements[i+1]))
		{
			// cout << elements[i] << " and " << elements[i+1] << " inc\n";
			string s=elements[i+1];
			string s1=elements[i];
			mint=999999999;
			bool flag=false;
			// cout << s[s.length()-1] << " " << s1[0] << endl;
			// cout << "check cost i+1\n";
			if(checkRev(s1,s)==true)
			{
				flag=true;
				// cout << "flag true\n";
				mint=costs[i];
			}
			// cout << "check cost i\n";
			if(checkRev(s,s1)==false)
			{
				// cout << "here too\n";
				if(flag)
				{
					mint=(mint<costs[i+1])?mint:costs[i+1];
					// cout << "mint:" << mint << endl;
				}
				else
				{
					// cout << "minttt:" << mint << endl;
					mint=costs[i+1];
				}
				flag=true;
			}
			// cout << "done\n";
			if(checkRev(s1,s)==false && checkRev(s,s1)==true)
			{
				cout << -1 << endl;
				break;
			}
			tot+=mint;
		}
		// cout << tot << endl;
	}
	if(i==n-1)
		cout << tot << endl;
}


#include <bits/stdc++.h>
using namespace std;
bool isCorrect(string a,string b)
{
	// cout << a << " " << b << endl;
	if(a.compare(b)<0)
	{
		// cout << "true\n";
		return true;
	}
	else
	{
		// cout << "false\n";
		return false;
	}
}
bool checkRev(string a,string b)
{
	long long i=a.length()-1,j=0;
	// // cout << "a:::" << a << " b:::" << b << endl;
	while(i>=0 && j<b.length())
	{
		if(a[i]>b[j])
		{
			// // cout << "f\n";
			return false;
		}
		else if(a[i]<b[j])
		{
			// // cout << "t\n";
			return true;
		}
		i--;
		j++;
	}
	if(a.length()<=b.length())
		return true;
	return false;
}
long long minimum(long long a,long long b)
{
	return (a<b)?a:b;
}
long long getRes(vector<string>&org,vector<string>&rev,vector<long long>&costs)
{
	long long dp_table[org.size()][2];
	long long i;
	for(i=0;i<org.size();i++)
	{
		dp_table[i][0]=LLONG_MAX;
		dp_table[i][1]=LLONG_MAX;
	}
	dp_table[0][0]=0;
	dp_table[0][1]=costs[0];
	for(i=1;i<org.size();i++)
	{
		if(org[i]>=org[i-1])
			dp_table[i][0]=dp_table[i-1][0];
		if(org[i]>=rev[i-1])
			dp_table[i][0]=minimum(dp_table[i][0],dp_table[i-1][1]);
		if(rev[i]>=org[i-1])
			dp_table[i][1]=dp_table[i-1][0]+costs[i];
		if(rev[i]>=rev[i-1])
			dp_table[i][1]=minimum(dp_table[i][1],dp_table[i-1][1]+costs[i]);
	}
	// cout << dp_table[org.size()-1][0] << " " << dp_table[org.size()-1][1] << endl;
	long long r=minimum(dp_table[org.size()-1][0],dp_table[org.size()-1][1]);
	if(r==LLONG_MAX)
		return -1;
	return r;
}
int main()
{
	long long n;
	vector<long long>costs;
	vector<string>elements;
	vector<string>elements_rev;
	long long i;
	cin >> n;
	for(i=0;i<n;i++)
	{
		long long elem;
		cin >> elem;
		costs.push_back(elem);
	}
	for(i=0;i<n;i++)
	{
		string s,s_rev;
		cin >> s;
		s_rev=s;
		reverse(s_rev.begin(),s_rev.end());
		elements.push_back(s);
		elements_rev.push_back(s_rev);
	}
	long long dp_res=getRes(elements,elements_rev,costs);
	cout << dp_res << endl;
	// long long tot=0,mint;
	// for(i=0;i<n-1;i++)
	// {
	// 	if(!isCorrect(elements[i],elements[i+1]))
	// 	{
	// 		// cout << elements[i] << " and " << elements[i+1] << " inc\n";
	// 		string s=elements[i+1];
	// 		string s1=elements[i];
	// 		string s_rev=s;
	// 		reverse(s_rev.begin(),s_rev.end());
	// 		string s1_rev=s1;
	// 		reverse(s1_rev.begin(),s1_rev.end());
	// 		mint=LONG_MAX;
	// 		bool flag=false;
	// 		if(isCorrect(s1_rev,s))
	// 		{
	// 			flag=true;
	// 			// cout << "flag true\n";
	// 			mint=costs[i];
	// 		}
	// 		// cout << "check cost i\n";

	// 		if(!isCorrect(s_rev,s1))
	// 		{
	// 			// cout << "here too\n";
	// 			if(flag)
	// 			{
	// 				mint=(mint<costs[i+1])?mint:costs[i+1];
	// 				// cout << "mint:" << mint << endl;
	// 			}
	// 			else
	// 			{
	// 				// cout << "minttt:" << mint << endl;
	// 				mint=costs[i+1];
	// 			}
	// 			flag=true;
	// 		}
	// 		// cout << "done\n";
	// 		if(checkRev(s1,s)==false && checkRev(s,s1)==true)
	// 		{
	// 			cout << -1 << endl;
	// 			break;
	// 		}
	// 		tot+=mint;
	// 	}
	// 	// cout << tot << endl;
	// }
	// if(i==n-1)
		// cout << tot << endl;
}


#include <bits/stdc++.h>
using namespace std;
const long long inf=0x3f3f3f3f3f3f3f3fll;
bool isCorrect(string a,string b)
{
	// cout << a << " " << b << endl;
	if(a.compare(b)<0)
	{
		// cout << "true\n";
		return true;
	}
	else
	{
		// cout << "false\n";
		return false;
	}
}
bool checkRev(string a,string b)
{
	long long i=a.length()-1,j=0;
	// // cout << "a:::" << a << " b:::" << b << endl;
	while(i>=0 && j<b.length())
	{
		if(a[i]>b[j])
		{
			// // cout << "f\n";
			return false;
		}
		else if(a[i]<b[j])
		{
			// // cout << "t\n";
			return true;
		}
		i--;
		j++;
	}
	if(a.length()<=b.length())
		return true;
	return false;
}
long long minimum(long long a,long long b)
{
	return (a<b)?a:b;
}
long long getRes(vector<string>&org,vector<string>&rev,vector<long long>&costs)
{
	// cout << LLONG_MAX << " " << LONG_MAX << endl;
	long long dp_table[org.size()][2];
	long long i;
	for(i=0;i<org.size();i++)
	{
		dp_table[i][0]=inf;
		dp_table[i][1]=inf;
	}
	dp_table[0][0]=0;
	dp_table[0][1]=costs[0];
	for(i=1;i<org.size();i++)
	{
		if(org[i]>=org[i-1])
			dp_table[i][0]=dp_table[i-1][0];
		if(org[i]>=rev[i-1])
			dp_table[i][0]=minimum(dp_table[i][0],dp_table[i-1][1]);
		if(rev[i]>=org[i-1])
			dp_table[i][1]=dp_table[i-1][0]+costs[i];
		if(rev[i]>=rev[i-1])
			dp_table[i][1]=minimum(dp_table[i][1],dp_table[i-1][1]+costs[i]);
	}
	// cout << dp_table[org.size()-1][0] << " " << dp_table[org.size()-1][1] << endl;
	long long r=minimum(dp_table[org.size()-1][0],dp_table[org.size()-1][1]);
	if(r==inf)
		return -1;
	return r;
}
int main()
{
	long long n;
	vector<long long>costs;
	vector<string>elements;
	vector<string>elements_rev;
	long long i;
	cin >> n;
	for(i=0;i<n;i++)
	{
		long long elem;
		cin >> elem;
		costs.push_back(elem);
	}
	for(i=0;i<n;i++)
	{
		string s,s_rev;
		cin >> s;
		s_rev=s;
		reverse(s_rev.begin(),s_rev.end());
		elements.push_back(s);
		elements_rev.push_back(s_rev);
	}
	// long long dp_res=getRes(elements,elements_rev,costs);
	// cout << dp_res << endl;
	long long tot=0,mint;
	for(i=0;i<n-1;i++)
	{
		if(!isCorrect(elements[i],elements[i+1]))
		{
			// cout << elements[i] << " and " << elements[i+1] << " inc\n";
			string s=elements[i+1];
			string s1=elements[i];
			string s_rev=s;
			reverse(s_rev.begin(),s_rev.end());
			string s1_rev=s1;
			reverse(s1_rev.begin(),s1_rev.end());
			mint=LONG_MAX;
			bool flag=false;
			if(isCorrect(s1_rev,s))
			{
				flag=true;
				// cout << "flag true\n";
				mint=costs[i];
			}
			// cout << "check cost i\n";

			if(!isCorrect(s_rev,s1))
			{
				// cout << "here too\n";
				if(flag)
				{
					mint=(mint<costs[i+1])?mint:costs[i+1];
					// cout << "mint:" << mint << endl;
				}
				else
				{
					// cout << "minttt:" << mint << endl;
					mint=costs[i+1];
				}
				flag=true;
			}
			if(isCorrect(s1_rev,s_rev)==true)
			{
				flag==true;
				mint=(mint<(costs[i]+costs[i+1]))?mint:costs[i]+costs[i+1];
			}
			// cout << "done\n";
			if(!flag)
			{
				cout << -1 << endl;
				break;
			}
			tot+=mint;
		}
		// cout << tot << endl;
	}
	if(i==n-1)
		cout << tot << endl;
}


#include <bits/stdc++.h>
using namespace std;
bool isCorrect(string a,string b)
{
	// cout << a << " " << b << endl;
	if(a.compare(b)<0)
	{
		// cout << "true\n";
		return true;
	}
	else
	{
		// cout << "false\n";
		return false;
	}
}
bool checkRev(string a,string b)
{
	long long i=a.length()-1,j=0;
	// // cout << "a:::" << a << " b:::" << b << endl;
	while(i>=0 && j<b.length())
	{
		if(a[i]>b[j])
		{
			// // cout << "f\n";
			return false;
		}
		else if(a[i]<b[j])
		{
			// // cout << "t\n";
			return true;
		}
		i--;
		j++;
	}
	if(a.length()<b.length())
		return true;
	return false;
}
int main()
{
	long long n;
	vector<long long>costs;
	vector<string>elements;
	long long i;
	cin >> n;
	for(i=0;i<n;i++)
	{
		long long elem;
		cin >> elem;
		costs.push_back(elem);
	}
	// // cout << "costs pushes\n";
	for(i=0;i<n;i++)
	{
		string s;
		cin >> s;
		elements.push_back(s);
	}
	// // cout << "strings pushed\n";
	long long tot=0,mint;
	for(i=0;i<n-1;i++)
	{
		if(!isCorrect(elements[i],elements[i+1]))
		{
			// cout << elements[i] << " and " << elements[i+1] << " inc\n";
			string s=elements[i+1];
			string s1=elements[i];
			mint=999999999;
			bool flag=false;
			// cout << s[s.length()-1] << " " << s1[0] << endl;
			// cout << "check cost i+1\n";
			if(checkRev(s1,s)==true)
			{
				flag=true;
				// cout << "flag true\n";
				mint=costs[i];
			}
			// cout << "check cost i\n";
			if(checkRev(s,s1)==false)
			{
				// cout << "here too\n";
				if(flag)
				{
					mint=(mint<costs[i+1])?mint:costs[i+1];
					// cout << "mint:" << mint << endl;
				}
				else
				{
					// cout << "minttt:" << mint << endl;
					mint=costs[i+1];
				}
				flag=true;
			}
			// cout << "done\n";
			if(!flag)
			{
				cout << -1 << endl;
				break;
			}
			tot+=mint;
		}
		// cout << tot << endl;
	}
	if(i==n-1)
		cout << tot << endl;
}


#include <bits/stdc++.h>
using namespace std;
bool isCorrect(string a,string b)
{
	// cout << a << " " << b << endl;
	if(a.compare(b)<0)
	{
		// cout << "true\n";
		return true;
	}
	else
	{
		// cout << "false\n";
		return false;
	}
}
bool checkRev(string a,string b)
{
	long long i=a.length()-1,j=0;
	// // cout << "a:::" << a << " b:::" << b << endl;
	while(i>=0 && j<b.length())
	{
		if(a[i]>b[j])
		{
			// // cout << "f\n";
			return false;
		}
		else if(a[i]<b[j])
		{
			// // cout << "t\n";
			return true;
		}
		i--;
		j++;
	}
	if(a.length()<=b.length())
		return true;
	return false;
}
int main()
{
	long long n;
	vector<long long>costs;
	vector<string>elements;
	long long i;
	cin >> n;
	for(i=0;i<n;i++)
	{
		long long elem;
		cin >> elem;
		costs.push_back(elem);
	}
	for(i=0;i<n;i++)
	{
		string s;
		cin >> s;
		elements.push_back(s);
	}
	long long tot=0,mint;
	for(i=0;i<n-1;i++)
	{
		if(!isCorrect(elements[i],elements[i+1]))
		{
			// cout << elements[i] << " and " << elements[i+1] << " inc\n";
			string s=elements[i+1];
			string s1=elements[i];
			string s_rev=s;
			reverse(s_rev.begin(),s_rev.end());
			string s1_rev=s1;
			reverse(s1_rev.begin(),s1_rev.end());
			mint=LONG_MAX;
			bool flag=false;
			if(isCorrect(s1_rev,s))
			{
				flag=true;
				// cout << "flag true\n";
				mint=costs[i];
			}
			// cout << "check cost i\n";

			if(!isCorrect(s_rev,s1))
			{
				// cout << "here too\n";
				if(flag)
				{
					mint=(mint<costs[i+1])?mint:costs[i+1];
					// cout << "mint:" << mint << endl;
				}
				else
				{
					// cout << "minttt:" << mint << endl;
					mint=costs[i+1];
				}
				flag=true;
			}
			// cout << "done\n";
			if(checkRev(s1,s)==false && checkRev(s,s1)==true)
			{
				cout << -1 << endl;
				break;
			}
			tot+=mint;
		}
		// cout << tot << endl;
	}
	if(i==n-1)
		cout << tot << endl;
}


#include <bits/stdc++.h>
using namespace std;
const long long inf=0x3f3f3f3f3f3f3f3fll;
bool isCorrect(string a,string b)
{
	// cout << a << " " << b << endl;
	if(a.compare(b)<0)
	{
		// cout << "true\n";
		return true;
	}
	else
	{
		// cout << "false\n";
		return false;
	}
}
bool checkRev(string a,string b)
{
	long long i=a.length()-1,j=0;
	// // cout << "a:::" << a << " b:::" << b << endl;
	while(i>=0 && j<b.length())
	{
		if(a[i]>b[j])
		{
			// // cout << "f\n";
			return false;
		}
		else if(a[i]<b[j])
		{
			// // cout << "t\n";
			return true;
		}
		i--;
		j++;
	}
	if(a.length()<=b.length())
		return true;
	return false;
}
long long minimum(long long a,long long b)
{
	return (a<b)?a:b;
}
long long getRes(vector<string>&org,vector<string>&rev,vector<long long>&costs)
{
	// cout << LLONG_MAX << " " << LONG_MAX << endl;
	long long dp_table[org.size()][2];
	long long i;
	for(i=0;i<org.size();i++)
	{
		dp_table[i][0]=inf;
		dp_table[i][1]=inf;
	}
	dp_table[0][0]=0;
	dp_table[0][1]=costs[0];
	for(i=1;i<org.size();i++)
	{
		if(org[i]>=org[i-1])
			dp_table[i][0]=dp_table[i-1][0];
		if(org[i]>=rev[i-1])
			dp_table[i][0]=minimum(dp_table[i][0],dp_table[i-1][1]);
		if(rev[i]>=org[i-1])
			dp_table[i][1]=dp_table[i-1][0]+costs[i];
		if(rev[i]>=rev[i-1])
			dp_table[i][1]=minimum(dp_table[i][1],dp_table[i-1][1]+costs[i]);
	}
	// cout << dp_table[org.size()-1][0] << " " << dp_table[org.size()-1][1] << endl;
	long long r=minimum(dp_table[org.size()-1][0],dp_table[org.size()-1][1]);
	if(r==inf)
		return -1;
	return r;
}
int main()
{
	long long n;
	vector<long long>costs;
	vector<string>elements;
	vector<string>elements_rev;
	long long i;
	cin >> n;
	for(i=0;i<n;i++)
	{
		long long elem;
		cin >> elem;
		costs.push_back(elem);
	}
	for(i=0;i<n;i++)
	{
		string s,s_rev;
		cin >> s;
		s_rev=s;
		reverse(s_rev.begin(),s_rev.end());
		elements.push_back(s);
		elements_rev.push_back(s_rev);
	}
	long long dp_res=getRes(elements,elements_rev,costs);
	cout << dp_res << endl;
	// long long tot=0,mint;
	// for(i=0;i<n-1;i++)
	// {
	// 	if(!isCorrect(elements[i],elements[i+1]))
	// 	{
	// 		// cout << elements[i] << " and " << elements[i+1] << " inc\n";
	// 		string s=elements[i+1];
	// 		string s1=elements[i];
	// 		string s_rev=s;
	// 		reverse(s_rev.begin(),s_rev.end());
	// 		string s1_rev=s1;
	// 		reverse(s1_rev.begin(),s1_rev.end());
	// 		mint=LONG_MAX;
	// 		bool flag=false;
	// 		if(isCorrect(s1_rev,s))
	// 		{
	// 			flag=true;
	// 			// cout << "flag true\n";
	// 			mint=costs[i];
	// 		}
	// 		// cout << "check cost i\n";

	// 		if(!isCorrect(s_rev,s1))
	// 		{
	// 			// cout << "here too\n";
	// 			if(flag)
	// 			{
	// 				mint=(mint<costs[i+1])?mint:costs[i+1];
	// 				// cout << "mint:" << mint << endl;
	// 			}
	// 			else
	// 			{
	// 				// cout << "minttt:" << mint << endl;
	// 				mint=costs[i+1];
	// 			}
	// 			flag=true;
	// 		}
	// 		// cout << "done\n";
	// 		if(checkRev(s1,s)==false && checkRev(s,s1)==true)
	// 		{
	// 			cout << -1 << endl;
	// 			break;
	// 		}
	// 		tot+=mint;
	// 	}
	// 	// cout << tot << endl;
	// }
	// if(i==n-1)
		// cout << tot << endl;
}


#include <bits/stdc++.h>
using namespace std;
const long long inf=0x3f3f3f3f3f3f3f3fll;
bool isCorrect(string a,string b)
{
	// cout << a << " " << b << endl;
	if(a.compare(b)<0)
	{
		// cout << "true\n";
		return true;
	}
	else
	{
		// cout << "false\n";
		return false;
	}
}
bool checkRev(string a,string b)
{
	long long i=a.length()-1,j=0;
	// // cout << "a:::" << a << " b:::" << b << endl;
	while(i>=0 && j<b.length())
	{
		if(a[i]>b[j])
		{
			// // cout << "f\n";
			return false;
		}
		else if(a[i]<b[j])
		{
			// // cout << "t\n";
			return true;
		}
		i--;
		j++;
	}
	if(a.length()<=b.length())
		return true;
	return false;
}
long long minimum(long long a,long long b)
{
	return (a<b)?a:b;
}
long long getRes(vector<string>&org,vector<string>&rev,vector<long long>&costs)
{
	// cout << LLONG_MAX << " " << LONG_MAX << endl;
	long long dp_table[org.size()][2];
	long long i;
	for(i=0;i<org.size();i++)
	{
		dp_table[i][0]=inf;
		dp_table[i][1]=inf;
	}
	dp_table[0][0]=0;
	dp_table[0][1]=costs[0];
	for(i=1;i<org.size();i++)
	{
		if(org[i]>=org[i-1])
			dp_table[i][0]=dp_table[i-1][0];
		if(org[i]>=rev[i-1])
			dp_table[i][0]=minimum(dp_table[i][0],dp_table[i-1][1]);
		if(rev[i]>=org[i-1])
			dp_table[i][1]=dp_table[i-1][0]+costs[i];
		if(rev[i]>=rev[i-1])
			dp_table[i][1]=minimum(dp_table[i][1],dp_table[i-1][1]+costs[i]);
	}
	// cout << dp_table[org.size()-1][0] << " " << dp_table[org.size()-1][1] << endl;
	long long r=minimum(dp_table[org.size()-1][0],dp_table[org.size()-1][1]);
	if(r==inf)
		return -1;
	return r;
}
int main()
{
	long long n;
	vector<long long>costs;
	vector<string>elements;
	vector<string>elements_rev;
	long long i;
	cin >> n;
	for(i=0;i<n;i++)
	{
		long long elem;
		cin >> elem;
		costs.push_back(elem);
	}
	for(i=0;i<n;i++)
	{
		string s,s_rev;
		cin >> s;
		s_rev=s;
		reverse(s_rev.begin(),s_rev.end());
		elements.push_back(s);
		elements_rev.push_back(s_rev);
	}
	// long long dp_res=getRes(elements,elements_rev,costs);
	// cout << dp_res << endl;
	long long tot=0,mint;
	for(i=0;i<n-1;i++)
	{
		if(!isCorrect(elements[i],elements[i+1]))
		{
			// cout << elements[i] << " and " << elements[i+1] << " inc\n";
			string s=elements[i+1];
			string s1=elements[i];
			string s_rev=s;
			reverse(s_rev.begin(),s_rev.end());
			string s1_rev=s1;
			reverse(s1_rev.begin(),s1_rev.end());
			mint=LONG_MAX;
			// cout << s << " " << s1 << " " << s_rev << " " << s1_rev << endl;
			bool flag=false;
			if(s1_rev<=s)
			{
				flag=true;
				// cout << "flag true\n";
				mint=costs[i];
			}
			// cout << "check cost i\n";

			if(s_rev>=s1)
			{
				// cout << "here too\n";
				if(flag)
				{
					mint=(mint<costs[i+1])?mint:costs[i+1];
					// cout << "mint:" << mint << endl;
				}
				else
				{
					// cout << "minttt:" << mint << endl;
					mint=costs[i+1];
				}
				flag=true;
			}
			if(!flag && s1_rev<=s_rev)
			{
				flag=true;
				mint=minimum(mint,costs[i]+costs[i+1]);
			}
			// cout << "done\n";
			if(!flag)
			{
				cout << -1 << endl;
				break;
			}
			if(flag && mint!=LONG_MAX)
				tot+=mint;
		}
		// cout << tot << endl;
	}
	if(i==n-1)
		cout << tot << endl;
}


#include <bits/stdc++.h>
using namespace std;
const long long inf=0x3f3f3f3f3f3f3f3fll;
bool isCorrect(string a,string b)
{
	// cout << a << " " << b << endl;
	if(a.compare(b)<0)
	{
		// cout << "true\n";
		return true;
	}
	else
	{
		// cout << "false\n";
		return false;
	}
}
bool checkRev(string a,string b)
{
	long long i=a.length()-1,j=0;
	// // cout << "a:::" << a << " b:::" << b << endl;
	while(i>=0 && j<b.length())
	{
		if(a[i]>b[j])
		{
			// // cout << "f\n";
			return false;
		}
		else if(a[i]<b[j])
		{
			// // cout << "t\n";
			return true;
		}
		i--;
		j++;
	}
	if(a.length()<=b.length())
		return true;
	return false;
}
long long minimum(long long a,long long b)
{
	return (a<b)?a:b;
}
long long getRes(vector<string>&org,vector<string>&rev,vector<long long>&costs)
{
	// cout << LLONG_MAX << " " << LONG_MAX << endl;
	long long dp_table[org.size()][2];
	long long i;
	for(i=0;i<org.size();i++)
	{
		dp_table[i][0]=inf;
		dp_table[i][1]=inf;
	}
	dp_table[0][0]=0;
	dp_table[0][1]=costs[0];
	for(i=1;i<org.size();i++)
	{
		if(org[i]>=org[i-1])
			dp_table[i][0]=dp_table[i-1][0];
		if(org[i]>=rev[i-1])
			dp_table[i][0]=minimum(dp_table[i][0],dp_table[i-1][1]);
		if(rev[i]>=org[i-1])
			dp_table[i][1]=dp_table[i-1][0]+costs[i];
		if(rev[i]>=rev[i-1])
			dp_table[i][1]=minimum(dp_table[i][1],dp_table[i-1][1]+costs[i]);
	}
	// cout << dp_table[org.size()-1][0] << " " << dp_table[org.size()-1][1] << endl;
	long long r=minimum(dp_table[org.size()-1][0],dp_table[org.size()-1][1]);
	if(r==inf)
		return -1;
	return r;
}
int main()
{
	long long n;
	vector<long long>costs;
	vector<string>elements;
	vector<string>elements_rev;
	long long i;
	cin >> n;
	for(i=0;i<n;i++)
	{
		long long elem;
		cin >> elem;
		costs.push_back(elem);
	}
	for(i=0;i<n;i++)
	{
		string s,s_rev;
		cin >> s;
		s_rev=s;
		reverse(s_rev.begin(),s_rev.end());
		elements.push_back(s);
		elements_rev.push_back(s_rev);
	}
	// long long dp_res=getRes(elements,elements_rev,costs);
	// cout << dp_res << endl;
	long long tot=0,mint;
	for(i=0;i<n-1;i++)
	{
		if(!isCorrect(elements[i],elements[i+1]))
		{
			// cout << elements[i] << " and " << elements[i+1] << " inc\n";
			string s=elements[i+1];
			string s1=elements[i];
			string s_rev=s;
			reverse(s_rev.begin(),s_rev.end());
			string s1_rev=s1;
			reverse(s1_rev.begin(),s1_rev.end());
			mint=LONG_MAX;
			// cout << s << " " << s1 << " " << s_rev << " " << s1_rev << endl;
			bool flag=false;
			if(s1_rev<s)
			{
				flag=true;
				// cout << "flag true\n";
				mint=costs[i];
			}
			// cout << "check cost i\n";

			if(s_rev>s1)
			{
				// cout << "here too\n";
				if(flag)
				{
					mint=(mint<costs[i+1])?mint:costs[i+1];
					// cout << "mint:" << mint << endl;
				}
				else
				{
					// cout << "minttt:" << mint << endl;
					mint=costs[i+1];
				}
				flag=true;
			}
			if(!flag && s1_rev<s_rev)
			{
				flag=true;
				mint=minimum(mint,costs[i]+costs[i+1]);
			}
			// cout << "done\n";
			if(!flag)
			{
				cout << -1 << endl;
				break;
			}
			if(flag && mint!=LONG_MAX)
				tot+=mint;
		}
		// cout << tot << endl;
	}
	if(i==n-1)
		cout << tot << endl;
}


#include <bits/stdc++.h>
using namespace std;
bool isCorrect(string a,string b)
{
	// cout << a << " " << b << endl;
	if(a.compare(b)<0)
	{
		// cout << "true\n";
		return true;
	}
	else
	{
		// cout << "false\n";
		return false;
	}
}
bool checkRev(string a,string b)
{
	long long i=a.length()-1,j=0;
	// // cout << "a:::" << a << " b:::" << b << endl;
	while(i>=0 && j<b.length())
	{
		if(a[i]>b[j])
		{
			// // cout << "f\n";
			return false;
		}
		else if(a[i]<b[j])
		{
			// // cout << "t\n";
			return true;
		}
		i--;
		j++;
	}
	if(a.length()<b.length())
		return true;
	return false;
}
int main()
{
	long long n;
	vector<long long>costs;
	vector<string>elements;
	long long i;
	cin >> n;
	for(i=0;i<n;i++)
	{
		long long elem;
		cin >> elem;
		costs.push_back(elem);
	}
	// // cout << "costs pushes\n";
	for(i=0;i<n;i++)
	{
		string s;
		cin >> s;
		elements.push_back(s);
	}
	// // cout << "strings pushed\n";
	long long tot=0,mint;
	for(i=0;i<n-1;i++)
	{
		if(!isCorrect(elements[i],elements[i+1]))
		{
			// cout << elements[i] << " and " << elements[i+1] << " inc\n";
			string s=elements[i+1];
			string s1=elements[i];
			mint=999999999;
			bool flag=false;
			// cout << s[s.length()-1] << " " << s1[0] << endl;
			// cout << "check cost i+1\n";
			if(checkRev(s1,s)==true)
			{
				flag=true;
				// cout << "flag true\n";
				mint=costs[i];
			}
			// cout << "check cost i\n";
			if(checkRev(s,s1)==false)
			{
				// cout << "here too\n";
				if(flag)
				{
					mint=(mint<costs[i+1])?mint:costs[i];
					// cout << "mint:" << mint << endl;
				}
				else
				{
					// cout << "minttt:" << mint << endl;
					mint=costs[i+1];
				}
				flag=true;
			}
			// cout << "done\n";
			if(!flag)
			{
				cout << -1 << endl;
				break;
			}
			tot+=mint;
		}
		// cout << tot << endl;
	}
	if(i==n-1)
		cout << tot << endl;
}


#include <bits/stdc++.h>

using namespace std;

#define pb push_back
#define mk make_pair
#define fi first
#define se second

typedef long long ll;
typedef pair<int, int> ii;

const ll INF = 1e14 + 400;
const double PI = acos(-1.0);
const double E = exp(1);

const int N = 1e5 + 5;
int n;
ll c[N];
ll dp[N][2];
string s[N];
string sa[N];

ll go (int at, bool ant) {
	if (at >= n) return 0;
	string str;

	ll& r = dp[at][ant];

	if (r != INF) return r;

	if (at != 0) {
		if (ant) {
			str = sa[at-1];
		} else {
			str = s[at-1];
		}
	}

	if (s[at] >= str)
		r = go(at+1, 0);

	if (sa[at] >= str) {
		ll x = go(at+1, 1) + c[at];
		r = min(r, x);
	}

	return r = min(r, INF);
}

int main (void) {
	ios_base::sync_with_stdio(false);

	for (int i = 0; i < N; i++)
		dp[i][0] = dp[i][1] = INF;

	cin >> n;

	for (int i = 0; i < n; i++)	cin >> c[i];
	for (int i = 0; i < n; i++)	cin >> s[i];

	for (int i = 0; i < n; i++)
		for (int j = s[i].size() - 1; j >= 0; j--)
			sa[i] += s[i][j];

	ll res = go(0,0);
	if (res >= INF) res = -1;

	cout << res << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define pb push_back
#define mk make_pair
#define fi first
#define se second

typedef long long ll;
typedef pair<int, int> ii;

const ll INF = 1e15;
const double PI = acos(-1.0);
const double E = exp(1);

const int N = 1e5 + 5;
int n;
ll c[N];
ll dp[N][2];
string s[N];
string sa[N];

ll go (int at, bool ant) {
	if (at >= n) return 0;
	string str;

	ll& r = dp[at][ant];

	if (r != INF) return r;

	if (at != 0) {
		if (ant) {
			str = sa[at-1];
		} else {
			str = s[at-1];
		}
	}

	if (s[at] >= str)
		r = go(at+1, 0);

	if (sa[at] >= str) {
		ll x = go(at+1, 1) + c[at];
		r = min(r, x);
	}

//	cout << at << " " << ant << ": " << r  << endl;
	return r;
}

int main (void) {
	ios_base::sync_with_stdio(false);

	for (int i = 0; i < N; i++)
		dp[i][0] = dp[i][1] = INF;

	cin >> n;

	for (int i = 0; i < n; i++)	cin >> c[i];
	for (int i = 0; i < n; i++)	cin >> s[i];

	for (int i = 0; i < n; i++)
		for (int j = s[i].size() - 1; j >= 0; j--)
			sa[i] += s[i][j];

	ll res = go(0,0);
	if (res >= INF) res = -1;

	cout << res << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define pb push_back
#define mk make_pair
#define fi first
#define se second

typedef long long ll;
typedef pair<int, int> ii;

const ll INF = 1e15;
const double PI = acos(-1.0);
const double E = exp(1);

const int N = 1e5 + 5;
int n;
ll c[N];
ll dp[N][2];
string s[N];
string sa[N];

ll go (int at, bool ant) {
	if (at >= n) return 0;
	string str;

	ll& r = dp[at][ant];

	if (r != INF) return r;

	if (at != 0) {
		if (ant) {
			str = sa[at-1];
		} else {
			str = s[at-1];
		}
	}

	if (s[at] >= str)
		r = go(at+1, 0);

	if (sa[at] >= str) {
		ll x = go(at+1, 1) + c[at];
		r = min(r, x);
	}
	r = min(r, INF);

//	cout << at << " " << ant << ": " << r  << endl;
	return r;
}

int main (void) {
	ios_base::sync_with_stdio(false);

	for (int i = 0; i < N; i++)
		dp[i][0] = dp[i][1] = INF;

	cin >> n;

	for (int i = 0; i < n; i++)	cin >> c[i];
	for (int i = 0; i < n; i++)	cin >> s[i];

	for (int i = 0; i < n; i++)
		for (int j = s[i].size() - 1; j >= 0; j--)
			sa[i] += s[i][j];

	ll res = go(0,0);
	if (res >= INF) res = -1;

	cout << res << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define pb push_back
#define mk make_pair
#define fi first
#define se second

typedef long long ll;
typedef pair<int, int> ii;

const double PI = acos(-1.0);
const double E = exp(1);

const int N = 1e5 + 5;
int n;
ll c[N];
ll dp[N][2];
string s[N];
string sa[N];

const ll INF = 1e15;

ll go (int at, bool ant) {
	if (at >= n) return 0;
	string str;

	ll& r = dp[at][ant];

	if (r < INF) return r;

	if (at != 0) {
		if (ant) {
			str = sa[at-1];
		} else {
			str = s[at-1];
		}
	}

	if (s[at] >= str)
		r = go(at+1, 0);

	if (sa[at] >= str) {
		ll x = go(at+1, 1) + c[at];
		r = min(r,x);
	}

//	cout << at << " " << ant << ": " << r  << endl;
	return r;
}

int main (void) {
	ios_base::sync_with_stdio(false);

	for (int i = 0; i < N; i++)
		dp[i][0] = dp[i][1] = INF;

	cin >> n;

	for (int i = 0; i < n; i++)	cin >> c[i];
	for (int i = 0; i < n; i++)	cin >> s[i];

	for (int i = 0; i < n; i++)
		for (int j = s[i].size() - 1; j >= 0; j--)
			sa[i] += s[i][j];

	ll res = go(0,0);
	if (res >= INF) res = -1;

	cout << res << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define pb push_back
#define mk make_pair
#define fi first
#define se second

typedef long long ll;
typedef pair<int, int> ii;

const ll INF = 1e14 + 400;
const double PI = acos(-1.0);
const double E = exp(1);

const int N = 1e5 + 5;
int n;
ll c[N];
ll dp[N][2];
string s[N];
string sa[N];

ll go (int at, bool ant) {
	if (at >= n) return 0;
	string str;

	ll& r = dp[at][ant];

	if (r != INF) return r;

	if (at != 0) {
		if (ant) {
			str = sa[at-1];
		} else {
			str = s[at-1];
		}
	}

	if (s[at] >= str)
		r = go(at+1, 0);

	if (sa[at] >= str) {
		ll x = go(at+1, 1) + c[at];
		r = min(r, x);
	}

	return r;
}

int main (void) {
	ios_base::sync_with_stdio(false);

	for (int i = 0; i < N; i++)
		dp[i][0] = dp[i][1] = INF;

	cin >> n;

	for (int i = 0; i < n; i++)	cin >> c[i];
	for (int i = 0; i < n; i++)	cin >> s[i];

	for (int i = 0; i < n; i++)
		for (int j = s[i].size() - 1; j >= 0; j--)
			sa[i] += s[i][j];

	ll res = go(0,0);
	if (res >= INF) res = -1;

	cout << res << endl;

	return 0;
}