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. AI 朴素贝叶斯分类

    1.条件概率 P(A|B)表示在事件B已经发生的条件下,事件A发生的概率.计算公式:P(A|B)=P(AB)/P(B). 2.相互独立事件 对于相互独立事件A和B,它们发生的概率互不影响,P(AB)= ...

  2. Omi框架学习之旅 - 通过omi-id来实现组件通讯 及原理说明

    这个demo是通过omi-id来获取子类的实例,然后更改data属性,之后updata一下就好了. 老规矩:先上demo代码, 然后提出问题, 之后解答问题, 最后源码说明. class Hello ...

  3. 理解maven中SNAPSHOT版本的作用

    https://leokongwq.github.io/2017/08/24/understanding-maven-snapshot.html 一次针对现有的http服务开发了一个SNAPSHOT版 ...

  4. Luogu2183 礼物 ExLucas、CRT

    传送门 证明自己学过exLucas 这题计算的是本质不相同的排列数量,不难得到答案是\(\frac{n!}{\prod\limits_{i=1}^m w_i! \times (n - \sum\lim ...

  5. Luogu P1477 [NOI2008]假面舞会

    一道非常神奇的图论题解法无比新奇清新 我们首先把图分成三种情况: 有环的,此时答案一定是环长的因数(否则不能满足题意) 存在入度大于1的DAG图的 一棵树/一条链 很容易发现,最后一种情况想怎么取就怎 ...

  6. asp.net core部署时自定义监听端口,提高部署的灵活性

    另一种方式 https://www.cnblogs.com/stulzq/p/9039836.html 代码截图: 贴一下代码,方便复制: //默认端口号5000 string port = &quo ...

  7. 【下一代核心技术DevOps】:(七)持续集成Jenkins的应用(Aliyun Pipiline持续构建)

    1. 前言 使用Jenkins比较好的就是可以在整个构建顺序中增加自定义的动作,比如构建成功给Leader发个邮件,给团队核心发个微信什么的. 当然最基本的核心还是它可以构建多种开发语言的项目,此类构 ...

  8. 支持自定义协议的虚拟仪器【winform版】

    首先,这个程序的由来,额,工作以来,做的最久的就是上位机,对市面上的大部分组态软件都感到不满,不好用,LabView虽然用起来不错,但是入门还是不够简单,刚好现在工作比较闲(已经不再做上位机了),所以 ...

  9. 分布式监控系统Zabbix-完整安装记录 -添加端口监控

    对于进程和端口的监控,可以使用zabbix自带的key进行监控,只需要在server端维护就可以了,相比于nagios使用插件去监控的方式更为简单.下面简单介绍配置:监控端口zabbix监控端口使用如 ...

  10. 《Linux内核分析》第八周

    <Linux内核分析>第八周 PART ONE 知识点总结 一.进程切换的关键代码switch_to 1.进程调度与进程调度的时机 (1)进程分类: I/O型(执行块,频繁) CPU型(大 ...