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. ESP32 DAC

    ESP32有两个DAC通道,通道1链接GPIO25, 通道2链接GPIO26; 当DAC设置为 “built-in DAC mode”的时候,I2S可以通过DAC发送数据: 使用示例: dac_out ...

  2. mysql导出CSV格式的文件

    select  *  from  Account  into outfile "/tmp/haha.csv" fields terminated by ',' lines term ...

  3. 数据库sql的in操作,解决in的过多

    一个sql的拼写后,服务器会把这个sql传送到数据库服务器执行,一般不在一个物理机上.那么传送需要走网络,包丢失等网络情况就可能出现. 一般情况,一个sql的长度不会很大,但是有种这样的情况.in操作 ...

  4. LiveCharts文档-3开始-3类型和设置

    原文:LiveCharts文档-3开始-3类型和设置 LiveCharts文档-3开始-3类型和设置 类型和设置 这一部分非常的重要,涉及到LiveCharts的基本构成单元的介绍 LiveChart ...

  5. Deep Learning(深度学习)学习笔记整理系列之(一)(转)

    Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0  2013-0 ...

  6. 一次Java内存泄漏调试的有趣经历

    人人都会犯错,但一些错误是如此的荒谬,我想不通怎么会有人犯这种错误.更没想到的是,这种事竟发生在了我们身上.当然,这种东西只有事后才能发现真相.接下来,我将讲述一系列最近在我们一个应用上犯过的这种错误 ...

  7. Lustre文件系统部署和应用探索

    1. Lustre文件系统概述 2. Lustre文件系统部署 2.1 基本环境 本篇博客将在KVM虚拟机中部署Lustre文件系统. 操作系统版本为CentOS6.5_x86_64.Lustre软件 ...

  8. 轮廓(Outline) 实例

    1.在元素周围画线本例演示使用outline属性在元素周围画一条线. <style type="text/css"> p{border:red solid thin;o ...

  9. Shell学习笔记二

    一.调试脚本 调试功能是每一种编程语言都应该实现的重要特性之一,当出现一些始料未及的情况时,用它来生成脚本运行信息.调试信息可以帮你弄清楚是什么原因使得程序发生崩溃或行为异常.每位系统程序员都应该了解 ...

  10. 数组与字符串三(Cocos2d-x 3.x _Array容器)

    "程序=数据结构+算法" 在面向对象的语言中,诸如数组.堆栈.队列等的结构都被封装成了特定的类,按照特定数据结构的算法设计起来,这就是容器类. Cocos2d-x中,能使用的容器类 ...