B - Hard problem

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个字符串,以及每条字符串变动所需的代价ci。问,能否通过只对某个或某些字符串进行翻转(即头尾调换,abcde->edcba),使这n条字符串为字典序排序(短的在前,小的在前)

 #include<bits/stdc++.h>
using namespace std; #define LL long long
const int maxn = ;
const LL INF=1e15; int c[maxn];
string str[maxn][];
LL dp[maxn][]; string reverse(string s){//翻转
string res=s;
int i, len=res.length();
for(i=;i<len/;++i)
swap(res[i], res[len--i]);
return res;
} int main(){
int n, i;
scanf("%d",&n);
for(i=;i<n;++i)
scanf("%d",&c[i]); for(i=;i<n;++i){
cin>>str[i][];
str[i][]=reverse(str[i][]);//翻转
} for(i=;i<n;++i)//初始化
dp[i][]=dp[i][]=INF;
dp[][]=; dp[][]=c[]; for(i=;i<n;++i){
if(str[i][]>=str[i-][])//原str i 大于 原str i-1
dp[i][]=dp[i-][];
if(str[i][]>=str[i-][])//翻转str i 大于 原str i-1
dp[i][]=dp[i-][]+c[i];
if(str[i][]>=str[i-][])//原str i 大于 翻转str i-1
dp[i][]=min(dp[i][],dp[i-][]);
if(str[i][]>=str[i-][])//翻转str i 大于 翻转str i-1
dp[i][]=min(dp[i][],dp[i-][]+c[i]);
if(dp[i][]==INF&&dp[i][]==INF)
break;
}
if(i==n)
printf("%I64d\n",min(dp[n-][],dp[n-][]));
else
printf("-1\n"); return ;
}

  这是今天训练的B题,但是我却放到了后面才做,因为我看不懂题意(即使是借助了翻译软件),最后去翻了外面的博客才读懂题意,所以读懂题意是解决问题的第一条件。

  代价ci,即使告诉我这是dp专题,我却怎么都没办法联系起来,一开始我甚至觉得ci是无关紧要的;但是当我们把ci和对相邻字符串的字典序的判断联系在一起时,这个题目就非常好做了。我们只要把dpi的初始值设置的非常大或者非常小,在循环中做判断时,如果通过所谓的字符翻转,能够实现字符串的字典序排序,我就将dpi的值改为ci(以便最后求出总的代价);如果不能实现字典序排序,那就不改变dpi的值,最后结束时只要判断dpi是否为初始设置的极端值,就能判断所有的字符串是否能按字典序排序。

  借助的dp数组,要巧妙的和需要求的值联系起来,既能作判断,又能求结果。

最新文章

  1. 通用权限管理系统多语言开发接口 - java,php 调用接口程序,多业务子系统集成
  2. PNG类库
  3. AIX主机信任关系配置
  4. JS图片加载失败显示默认图片
  5. SQL Server -SET QUOTED_IDENTIFIER
  6. 嵌入式linux的网络编程(1)--TCP/IP协议概述
  7. Linux - 输入输出流程序 代码(C)
  8. CF 17B Hierarchy
  9. 跑Java -jar somefile.jar时会发生什么(一个)
  10. 2017-12-19python全栈9期第四天第二节之列表的增删查改之删除的pop和del和remove和clear
  11. i春秋-百度杯十月场-fuzzing
  12. build script和all projects作用和区别
  13. 搭建单机版的FastDFS服务
  14. windows下Qt播放flash
  15. ipv6的校验格式
  16. Java学习路线:Java中的位移运算符介绍
  17. Java匿名内部类的继承者、终结者————lambda表达式
  18. Vue.js基础(二)
  19. 重识linux-关于selinux
  20. Mogodb 学习一

热门文章

  1. Picture POJ - 1177 线段树+离散化+扫描线 求交叉图像周长
  2. Fabric智能合约(base)
  3. springboot web - 启动(1) 创建SpringApplication
  4. Microsoft visual studio 2015已停止工作最全解决办法
  5. 递归查询 start with connect by prior
  6. SGDClassifier梯度下降分类方法
  7. word的一些运用技巧
  8. 使用vue/cli 创建一个简单的项目
  9. Android 基础知识 -- BroadcastReceiver
  10. Docker最全教程——从理论到实战(二十)