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 exceed100 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.

Sample Input

Input
2
1 2
ba
ac
Output
1
Input
3
1 3 1
aa
ba
ac
Output
1
Input
2
5 5
bbb
aaa
Output
-1
Input
2
3 3
aaa
aa
Output
-1

Hint

In the second sample one has to reverse string 2 or string 3. To amount of energy required to reverse the string 3 is
smaller.

In the third sample, both strings do not change after reverse and they go in the wrong order, so the answer is  - 1.

In the fourth sample, both strings consists of characters 'a' only, but in the sorted order string "aa" should go before string "aaa", thus
the answer is  - 1.

【题解】

意思是说每个字符串只能倒转或不倒转。(逆序)

然后要求n个字符串最后为有序的。s[i]>=s[i-1];

每个字符串倒转都需要耗费能量c[i]

设f[i][0]表示第i个字符串不倒转所需要的最少能量。

f[i][1]表示第i个字符串倒转所需要的最少能量。

然后用一个结构体记录每一个字符不倒转的样子和倒转过后的样子。->zhengs,fans;

因为你在处理第I个,如果前i-1个不是升序的。那改变第i个毫无意义。

所以如果f[i][0]==-1或f[i][1] ==-1,则表示这个状态不符合升序的要求。不能由这个状态推出下一个状态。

然后每次把存zhengs和fans的a[]数组的a[i].zhengs->a[i-1].fans,a[i-1].zhengs(对应f[i-1][1],f[i-1][0])进行比较如果满足a[i].zhengs>=后面两个字符则f[i][0]=min(f[i-1][0],f[i-1][1]);前提是f[i-1][0]或f[i-1][1]这个状态存在!

然后a[i].fans->a[i-1].fans,a[i-1].zhengs(对应f[i-1][1],f[i-1][0]).如果满足a[i].fans>=后面两个字符串。则f[i][1]和f[i-1][0]或f[i-1][1]取较小值。同样要求这个状态要存在才行!

【代码】

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream> using namespace std; struct ss
{
string zhengs, fans;//用来存正的序列和反向之后的序列。
}; ss a[100001];
__int64 f[100001][2], c[100001];
int n; int main()
{
//freopen("F:\\rush.txt", "r", stdin);
//freopen("F:\\rush_out.txt", "w", stdout);
scanf("%d", &n);
for (int i = 1; i <= n; i++)//读入对某一个操作需要的能量值。
scanf("%I64d", &c[i]);
char s[100001];
for (int i = 1; i <= n; i++)//读入n个字符串
{
scanf("%s", s);//用scanf读会快一点。
a[i].zhengs = string(s);
a[i].fans = string(s);
int begin = 0, end = a[i].zhengs.size() - 1;
while (begin <= end)//进行反转的过程
{
a[i].fans[begin] = a[i].zhengs[end];
a[i].fans[end] = a[i].zhengs[begin];
begin++; end--;
}
}
memset(f, 255, sizeof(f));//一开始所有的状态都无法到达。
f[1][0] = 0; f[1][1] = c[1];//初值表示前1个字符串,不反转则消耗为0,翻转则消耗为c[1]
for (int i = 2; i <= n; i++)
{
if (a[i].zhengs >= a[i - 1].zhengs && f[i - 1][0] != -1)//根据上面题解的规则写转移就可以了。
f[i][0] = f[i - 1][0];
if (a[i].zhengs >= a[i - 1].fans && f[i - 1][1] != -1)
if (f[i][0] == -1 || f[i][0] > f[i - 1][1])
f[i][0] = f[i - 1][1]; //要注意。一定要f[i-1][x]这个状态存在才能转移。
if (a[i].fans >= a[i - 1].zhengs && f[i - 1][0] != -1)
f[i][1] = f[i - 1][0] + c[i];
if (a[i].fans >= a[i - 1].fans && f[i - 1][1] != -1)
if (f[i][1] == -1 || f[i][1] > f[i - 1][1] + c[i])
f[i][1] = f[i - 1][1] + c[i];
}
__int64 ans = f[n][1];//最后取f[n][1],f[n][0]中的较小值
if (f[n][0] < f[n][1])
ans = f[n][0];//如果较小值是-1,就取f[n][1],f[n][0]中的较大值。
if (ans == -1) //如果最小值是-1,则取最大值。这样就能指向答案了(当然,如果还是-1则答案是-1)
{
__int64 temp = f[n][1];
if (f[n][0] > f[n][1])
temp = f[n][0];
ans = temp;
}
printf("%I64d", ans);
return 0;
}

【CF706C】Hard problem的更多相关文章

  1. 【Luogu4137】Rmq Problem/mex (莫队)

    [Luogu4137]Rmq Problem/mex (莫队) 题面 洛谷 题解 裸的莫队 暴力跳\(ans\)就能\(AC\) 考虑复杂度有保证的做法 每次计算的时候把数字按照大小也分块 每次就枚举 ...

  2. 【BZOJ2302】[HAOI2011]Problem C(动态规划)

    [BZOJ2302][HAOI2011]Problem C(动态规划) 题面 BZOJ 洛谷 题解 首先如果\(m=0\)即没有特殊限制的话,那么就和这道题目基本上是一样的. 然而这题也有属于这题的性 ...

  3. 【BZOJ4999】This Problem Is Too Simple!(线段树)

    [BZOJ4999]This Problem Is Too Simple!(线段树) 题面 BZOJ 题解 对于每个值,维护一棵线段树就好啦 动态开点,否则空间开不下 剩下的就是很简单的问题啦 当然了 ...

  4. 【BZOJ2298】[HAOI2011]problem a DP

    [BZOJ2298][HAOI2011]problem a Description 一次考试共有n个人参加,第i个人说:“有ai个人分数比我高,bi个人分数比我低.”问最少有几个人没有说真话(可能有相 ...

  5. 【bzoj3339】Rmq Problem

    [bzoj3339]Rmq Problem   Description Input Output Sample Input 7 50 2 1 0 1 3 21 32 31 43 62 7 Sample ...

  6. 【BZOJ4999】This Problem Is Too Simple! 离线+树状数组+LCA

    [BZOJ4999]This Problem Is Too Simple! Description 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2 ...

  7. 【计算几何】FZU Problem 2270 Two Triangles

    http://acm.fzu.edu.cn/problem.php?pid=2270 [题意] 给定6到10个点,从中选出6个不同的点组成两个三角形,使其中一个三角形可以通过另一个三角形平移和旋转得到 ...

  8. 【HDU】6242-Geometry Problem

    今天忽然心血来潮打开牛客网尝试了一下一站到底 前四道题都是不到二十分钟切完,然后第五道来了道计算几何 我也不会啊,于是就觉得大力随机也许可行 然鹅被精度卡到崩溃 后来我才知道 保证有解,是保证你的精度 ...

  9. 【搜索】Partition problem

    题目链接:传送门 题面: [题意] 给定2×n个人的相互竞争值,请把他们分到两个队伍里,如果是队友,那么竞争值为0,否则就为v[i][j]. [题解] 爆搜,C(28,14)*28,其实可以稍加优化, ...

随机推荐

  1. Direct2D开发:向 MFC 项目添加 Direct2D 对象

    0X01 创建 MFC 应用程序: 在“文件”菜单上指向“新建”,然后单击“项目”. 在“新建项目”对话框左窗格的“已安装的模板”下,展开“Visual C++”,然后选择“MFC”. 在中间窗格中, ...

  2. Method of address space layout randomization for windows operating systems

    A system and method for address space layout randomization ("ASLR") for a Windows operatin ...

  3. 洛谷 P2692 覆盖

    P2692 覆盖 题目背景 WSR的学校有B个男生和G个女生都来到一个巨大的操场上扫地. 题目描述 操场可以看成是N 行M 列的方格矩阵,如下图(1)是一个4 行5 列的方格矩阵.每个男生负责打扫一些 ...

  4. Spark源代码分析之中的一个:Job提交执行总流程概述

    Spark是一个基于内存的分布式计算框架.执行在其上的应用程序,依照Action被划分为一个个Job.而Job提交执行的总流程.大致分为两个阶段: 1.Stage划分与提交 (1)Job依照RDD之间 ...

  5. C#里如何把一个DataTable的数据追加进数据库里的某个表

    方法一: DataTable table = new DataTable(); //TODO: init table... string connStr = "user id=" ...

  6. Flask项目之手机端租房网站的实战开发(八)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...

  7. Docker安装RabbitMQ,RabbitMQ Management使用

    原文:Docker安装RabbitMQ,RabbitMQ Management使用 版权声明:本文为博主原创文章,未经博主允许不得转载.需要转载请先评论或者邮箱联系我,谢谢! https://blog ...

  8. CMake - SWIG - 移植动态库

    CMake - SWIG 最后更新日期:2014-04-25 bykagula 阅读前提:<CMake入门(二)>.<同Java的混合编程-SWIG>.Linux的基本操作.j ...

  9. 1.4 Python基础知识 - 代码书写格式及条件判断"if ... else ..."

    一.代码的书写规则 在所有的开发语言中,代码之间都是有关联的关系,有的是包含关系,有的是上下级关系,有的是代表语句的结束.在python中也是有相应的规则的: 1.在没有上下级关系的代码中,代码要顶行 ...

  10. 鲁德http://www.testroad.org/topic/76

     [最新的招聘信息]:1.联动优势科技有限公司招聘性能测试工程师       薪资20K左右 http://ask.testroad.org/article/4042.上海-交通银行总行-性能测试专家 ...