Hard problem

CodeForces - 706C

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

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

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

Input

第一行包含一个整数 n (2 ≤ n ≤ 100 000) — 表示字符串的数量。

第二行包含 n 个整数 ci (0 ≤ ci ≤ 109),第 i 个整数等于翻转第 i 个字符串所需的能量。

之后 n 行,每行包含一个小写英文字母。总长度不到 100 000。

Output

如果不可能有序,输出  - 1。否则输出最小所需的能量。

Example

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

Note

第二个样例中翻转字符串 2 或字符串 3。翻转字符串 3 所需能量更少。

第三个样例不合法,所以输出  - 1。

第四个样例不合法,所以输出  - 1。

sol:dp较为明显,因为i-2及之前的翻转是不影响当前的转移的,dp[i][0/1]表示在第i个字符串,当前是否翻转

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read()
{
ll s=;
bool f=;
char ch=' ';
while(!isdigit(ch))
{
f|=(ch=='-'); ch=getchar();
}
while(isdigit(ch))
{
s=(s<<)+(s<<)+(ch^); ch=getchar();
}
return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
if(x<)
{
putchar('-'); x=-x;
}
if(x<)
{
putchar(x+''); return;
}
write(x/);
putchar((x%)+'');
return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=;
int n;
ll Cost[N],dp[N][];
char S_Last[N],S_Now[N];
inline bool Judge(char *S1,char *S2)
{
int i,n1=strlen(S1+),n2=strlen(S2+);
for(i=;i<=min(n1,n2);i++) if(S1[i]!=S2[i])
{
return S1[i]<S2[i];
}
return (n1<=n2)?:;
}
int main()
{
int i,j;
R(n);
for(i=;i<=n;i++) R(Cost[i]);
scanf("%s",S_Last+);
memset(dp,,sizeof dp);
dp[][]=;
dp[][]=Cost[];
for(i=;i<=n;i++)
{
scanf("%s",S_Now+);
if(Judge(S_Last,S_Now))
{
dp[i][]=min(dp[i][],dp[i-][]);
}
reverse(S_Last+,S_Last+strlen(S_Last+)+);
if(Judge(S_Last,S_Now))
{
dp[i][]=min(dp[i][],dp[i-][]);
}
reverse(S_Now+,S_Now+strlen(S_Now+)+);
if(Judge(S_Last,S_Now))
{
dp[i][]=min(dp[i][],dp[i-][]+Cost[i]);
}
reverse(S_Last+,S_Last+strlen(S_Last+)+);
if(Judge(S_Last,S_Now))
{
dp[i][]=min(dp[i][],dp[i-][]+Cost[i]);
}
reverse(S_Now+,S_Now+strlen(S_Now+)+);
memmove(S_Last,S_Now,sizeof S_Last);
}
if(min(dp[n][],dp[n][])>) puts("-1");
else Wl(min(dp[n][],dp[n][]));
return ;
}
/*
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
*/

codeforces706C的更多相关文章

随机推荐

  1. linux中断源码分析 - 初始化(二)

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 本篇文章主要讲述源码中是如何对中断进行一系列的初始化的. 回顾 在上一篇概述中,介绍了几个对于中断来说非常重要的 ...

  2. NPOI DataTable导出excel

    /// <summary> /// DataTable导出到Excel文件 /// </summary> /// <param name="dtSource&q ...

  3. Luogu2612 ZJOI2012 波浪 DP

    传送门 花掉了自己用来搞学科的时间做了这道题-- 一道类似的题:Here 考虑拆开绝对值计算贡献.那么我们对于\(1\)到\(N\)的排列,从小到大地将插入它们插入排列中. 假设我们现在计算到了数\( ...

  4. Vue-Vue文本渲染三种方法 {{}}、v-html、v-text

    {{ }} 将元素当成纯文本输出 v-htmlv-html会将元素当成HTML标签解析后输出 v-textv-text会将元素当成纯文本输出 代码: <!DOCTYPE html> < ...

  5. 控制反转IOC与依赖注入DI - 理论篇

    学无止境,精益求精 十年河东十年河西,莫欺少年穷 昨天是五一小长假归来上班的第一天,身体疲劳,毫无工作热情.于是就看看新闻,喝喝茶,荒废了一天 也就在昨天,康美同事张晶童鞋让我学习下IOC的理论及实现 ...

  6. Ubuntu16.04密码正确 进不去桌面系统(已测试恢复正常)

    遇到过两次ubuntu输入密码正确,但是进不去系统,输入密码后,跳转到一下界面 之后又返回到登陆界面,一直这样循环输入密码. Guest用户可以.   解决办法: 1.进入tty下           ...

  7. python语言程序设计7

    1, 特么的打个空格出现就出现个点是个怎么回事, 昨天虽然是我复制的代码,,但也是我一点一点写出来的啊.. 复制的时候缩进直接就没了.我去 但是我感觉它一开始给我讲的一些基础理论又有点忘了,我希望你能 ...

  8. [开源 .NET 跨平台 Crawler 数据采集 爬虫框架: DotnetSpider] [五] 如何做全站采集?

    [DotnetSpider 系列目录] 一.初衷与架构设计 二.基本使用 三.配置式爬虫 四.JSON数据解析与配置系统 五.如何做全站采集 如何做全站采集? 很多同学加群都在问, 如何使用Dotne ...

  9. Jmeter(三十二)_搭建本地接口自动化环境

    我们在学习接口自动化的时候,最理想的状态是在公司有项目可以操作.大部分时候我们并没有可以练习的项目,因此练习接口无从谈起,只能找一些开放的api来练一练,但是这样并不能提高我们的技术.因此我们需要搭建 ...

  10. CSS 表格实例

    CSS 表格实例CSS 表格属性可以帮助您极大地改善表格的外观.CSS Table 属性属性 描述border-collapse 设置是否把表格边框合并为单一的边框.border-spacing 设置 ...