CF706C Hard problem 题解

题目链接

Description

Vasiliy is fond of solving different tasks. Today he found one he wasn't able to solve himself, so he asks you to help.

Vasiliy is given n strings consisting of lowercase English letters. He wants them to be sorted in lexicographical order (as in the dictionary), but he is not allowed to swap any of them. The only operation he is allowed to do is to reverse any of them (first character becomes last, second becomes one before last and so on).

To reverse the i-th string Vasiliy has to spent ci units of energy. He is interested in the minimum amount of energy he has to spent in order to have strings sorted in lexicographical order.

String A is lexicographically smaller than string B if it is shorter than B (|A| < |B|) and is its prefix, or if none of them is a prefix of the other and at the first position where they differ character in A is smaller than the character in B.

For the purpose of this problem, two equal strings nearby do not break the condition of sequence being sorted lexicographically.

Input

The first line of the input contains a single integer n (2 ≤ n ≤ 100 000) — the number of strings.

The second line contains n integers ci (0 ≤ ci ≤ 109), the i-th of them is equal to the amount of energy Vasiliy has to spent in order to reverse the i-th string.

Then follow n lines, each containing a string consisting of lowercase English letters. The total length of these strings doesn't exceed 100 000.

Output

If it is impossible to reverse some of the strings such that they will be located in lexicographical order, print  - 1. Otherwise, print the minimum total amount of energy Vasiliy has to spent.

题目大意

现在有 n 个由小写字母组成的字符串。他想要让这些字符串按字典序排列,但是他不能交换任意两个字符串。他唯一能做的事是翻转字符串。

翻转第 i 个字符串需要花费 ci 的能量。他想知道将所有字符串排序最少要多少能量。

两个相邻的字符串可以相等,不一定要严格递增。

2 ≤ n ≤ 100000,0 ≤ ci ≤ 109,字符串总长不超过100000

题解

首先我们可以考虑前i个字符串,假如这些字符串已经是有序的了,那么我们关心的只有所需的能量以及第i个字符串是否被翻转了,之前的每个字符串是否被翻转对之后的字符串没有任何影响。

所以我们可以用fi表示第i个字符串不翻转,之前的所以字符串有序的情况下所需的最少能量,用gi表示第i个字符串翻转,之前的所以字符串有序的情况下所需的最少能量。

之后我们只要暴力判断一下两个相邻的字符串分别翻转/不翻转的大小关系即可。

code

代码和题解有点不太一样,f[i][0]表示第i个位置不翻转,之前的所以字符串有序的情况下所需的最少能量值。f[i][1]表示第i个位置翻转,之前的所以字符串有序的情况下所需的最少能量值。(即把数组f和数组g合起来了QAQ)

我的代码→submission

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 const int N=1e5+5,inf=1e18;
 5 string s[N][2];
 6 int n,c[N],f[N][2],ans;
 7 void work(){
 8     for(int i=1;i<=n;i++){
 9         cin>>s[i][0];
10         s[i][1]=s[i][0];
11         reverse(s[i][1].begin(),s[i][1].end());
12         for(int j=0;j<2;j++){
13             f[i][j]=inf;
14             for(int k=0;k<2;k++)
15                 if(s[i][j]>=s[i-1][k]) f[i][j]=min(f[i][j],f[i-1][k]+j*c[i]);
16         }
17     }
18     ans=min(f[n][0],f[n][1]);
19 }
20 signed main(){
21     //freopen(".in","r",stdin);
22     //freopen(".out","w",stdout);
23     scanf("%lld",&n);
24     for(int i=1;i<=n;i++)
25         scanf("%lld",&c[i]);
26     work();
27     if(ans==inf) printf("-1\n");
28     else printf("%lld\n",ans);
29     return 0;
30 }

猜你喜欢

转载自www.cnblogs.com/maoyiting/p/CF706C.html
今日推荐