题目链接:

C. Hard problem

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

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.

Examples
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
题意:
 
问把这些字符串按字典序排好,如果第i个需要倒转,花费为a[i],现在求最小花费;
 
思路:
 
dp[i][j]表示第i个串的状态为j时的最小花费,j==0表示不倒转,j==1表示倒转;转移方程看代码;
 
AC代码:
 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <bits/stdc++.h>
using namespace std; #define For(i,j,n) for(int i=j;i<=n;i++)
#define mst(ss,b) memset(ss,b,sizeof(ss)); typedef long long LL; template<class T> void read(T&num) {
char CH; bool F=false;
for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p) {
if(!p) { puts("0"); return; }
while(p) stk[++ tp] = p%10, p/=10;
while(tp) putchar(stk[tp--] + '0');
putchar('\n');
} const LL mod=998244353;
const double PI=acos(-1.0);
const LL inf=1e18;
const int N=1e5+10;
const int maxn=1e3+10;
const double eps=1e-4; int n;
LL a[N],dp[N][2];
string s[N]; int main()
{
read(n);
For(i,1,n)read(a[i]);
For(i,0,n)dp[i][0]=dp[i][1]=inf;
For(i,1,n)
{
cin>>s[i];
if(i==1){dp[i][0]=0,dp[i][1]=a[1];continue;}
if(s[i]>=s[i-1])dp[i][0]=min(dp[i][0],dp[i-1][0]);
string temp="";
int len=s[i-1].length();
for(int j=len-1;j>=0;j--)
{
temp=temp+s[i-1][j];
}
if(s[i]>=temp)dp[i][0]=min(dp[i][0],dp[i-1][1]);
string t="";
len=s[i].length();
for(int j=len-1;j>=0;j--)t=t+s[i][j];
if(t>=s[i-1])dp[i][1]=min(dp[i][1],dp[i-1][0]+a[i]);
if(t>=temp)dp[i][1]=min(dp[i][1],dp[i-1][1]+a[i]);
}
LL ans=min(dp[n][0],dp[n][1]);
if(ans==inf)cout<<"-1";
else cout<<ans;
return 0;
}

  

codeforces 706C C. Hard problem(dp)的更多相关文章

  1. Codeforces 706 C. Hard problem (dp)

    题目链接:http://codeforces.com/problemset/problem/706/C 给你n个字符串,可以反转任意一个字符串,反转每个字符串都有其对应的花费ci. 经过操作后是否能满 ...

  2. 【动态规划】Codeforces 706C Hard problem

    题目链接: http://codeforces.com/contest/706/problem/C 题目大意: n(2 ≤ n ≤ 100 000)个字符串(长度不超过100000),翻转费用为Ci( ...

  3. codeforces C. Sonya and Problem Wihtout a Legend(dp or 思维)

    题目链接:http://codeforces.com/contest/713/problem/C 题解:这题也算是挺经典的题目了,这里附上3种解法优化程度层层递进,还有这里a[i]-i<=a[i ...

  4. codeforces 721C (拓排 + DP)

    题目链接:http://codeforces.com/contest/721/problem/C 题意:从1走到n,问在时间T内最多经过多少个点,按路径顺序输出. 思路:比赛的时候只想到拓排然后就不知 ...

  5. Codeforces 543D. Road Improvement (树dp + 乘法逆元)

    题目链接:http://codeforces.com/contest/543/problem/D 给你一棵树,初始所有的边都是坏的,要你修复若干边.指定一个root,所有的点到root最多只有一个坏边 ...

  6. Codeforces 467C. George and Job (dp)

    题目链接:http://codeforces.com/contest/467/problem/C 求k个不重叠长m的连续子序列的最大和. dp[i][j]表示第i个数的位置个序列的最大和. 前缀和一下 ...

  7. CodeForces 163A Substring and Subsequence dp

    A. Substring and Subsequence 题目连接: http://codeforces.com/contest/163/problem/A Description One day P ...

  8. Codeforces 834D The Bakery【dp+线段树维护+lazy】

    D. The Bakery time limit per test:2.5 seconds memory limit per test:256 megabytes input:standard inp ...

  9. codeforces#1154F. Shovels Shop (dp)

    题目链接: http://codeforces.com/contest/1154/problem/F 题意: 有$n$个物品,$m$条优惠 每个优惠的格式是,买$x_i$个物品,最便宜的$y_i$个物 ...

随机推荐

  1. 如何让<input type="text" />中的文字居中

    高(height)和行高(line-height)相等.不能用vertical-align

  2. Html5 播放Hls格式视频

    二群号为766718184 ,博主提供Ffmpeg.GB28181视频教程 播放地址: http://www.iqiyi.com/u/1426749687  移动端Html5支持Hls格式视频播放,创 ...

  3. 常用string函数分析

    string函数分析string函数包含在string.c文件中,经常被C文件使用.1. strcpy函数原型: char* strcpy(char* str1,char* str2);函数功能: 把 ...

  4. Double类parseDouble()和valueOf()方法的区别

    数字类型的String字符串转换为浮点数通常采用parseDouble()和valueOf()方法, 两者主要是存在以下两点区别. 区别一:参数区别Double.parseDouble(java.la ...

  5. 10 redis--频道发布与消息订阅

    消息订阅 使用办法: 订阅端: Subscribe 频道名称 发布端: publish 频道名称 发布内容 客户端例子: redis 127.0.0.1:6379> subscribe news ...

  6. ant 可自动替换友盟渠道、版本号、包名

    可自动替换友盟渠道.版本号.包名 如何集成到我的项目里 前提:了解android官方文档,在项目目录中执行ant debug能打包,比如常见的打包步骤: android update project ...

  7. Unity3D研究院编辑器之自定义默认资源的Inspector面板

    比如编辑模式下对场景或者特定文件夹有一些操作可以在这个面板里来完成. 代码如下: using System.Collections; using System.Collections.Generic; ...

  8. python 基础 4.4 生成式 生成器 迭代器

    一.生成式和生成器   列表生成式是python受欢迎的语法之一,通过一句简洁的语法就可以对一组元素进行过滤,还可以对得到的元素进行转换处理.   #/usr/bin/python #coding=u ...

  9. 九度OJ 1145:Candy Sharing Game(分享蜡烛游戏) (模拟)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:248 解决:194 题目描述: A number of students sit in a circle facing their teac ...

  10. 【网络与系统安全】利用burpsuite进行重放攻击

    重放攻击的定义 所谓重放攻击就是攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程. 原理 重放攻击的基本原理就是把以前窃听到的数据原封不动地重新发送给接收方.如果攻击者知 ...