- 题目链接:http://codeforces.com/contest/706/problem/C
- 题意:要使n个字符串变为字典序。只能进行一种操作:将第i个字符串reverse,并消耗c[i]的能量。求消耗的最小的能量
- 算法:数据量100000,时限1s,只能用dp
- 思路:
- 状态:dp[i][j]表示前i个字符串变为字典序所消耗的最小能量。j==0时表示第i个字符串不反转,j==1时表示第i个字符串反转。
- 转移:dp[i][j] = min( dp[i][j], dp[i-1][0] + c[i]*j), dp[i][j] = min(dp[i][j], dp[i-1][1] + c[i]*j);
#include <bits/stdc++.h>
#define pi acos(-1)
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const int maxn = 3e5 + 10;
const int mod = 1e9 + 7;
int c[maxn];
string s[maxn], tmp, pre;
LL dp[maxn][5];
int main()
{
memset(dp, LL_INF, sizeof(dp));
fastio;
int n; cin >> n;
for(int i=0; i<n; i++){
cin >> c[i];
}
for(int i=0; i<n; i++){
cin >> s[i];
}
dp[0][0] = 0;
dp[0][1] = c[0];
tmp = s[0];
reverse(tmp.begin(), tmp.end());
pre = tmp;
for(int i=1; i<n; i++){
tmp = s[i];
reverse(tmp.begin(), tmp.end());
if(s[i] >= s[i-1]){
dp[i][0] = min(dp[i][0], dp[i-1][0]);
}
if(s[i] >= pre){
dp[i][0] = min(dp[i][0], dp[i-1][1]);
}
if(tmp >= s[i-1]){
dp[i][1] = min(dp[i][1], dp[i-1][0]+c[i]);
}
if(tmp >= pre){
dp[i][1] = min(dp[i][1], dp[i-1][1]+c[i]);
}
pre = tmp;
}
LL ans = min(dp[n-1][0],dp[n-1][1]);
if(ans >= LL_INF) cout << "-1" << endl;
else cout << ans << endl;
}