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数组,要巧妙的和需要求的值联系起来,既能作判断,又能求结果。

dp--B - Hard problem的更多相关文章

  1. poj3311 TSP经典状压dp(Traveling Saleman Problem)

    题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...

  2. 递推DP HDOJ 5328 Problem Killer

    题目传送门 /* 递推DP: 如果a, b, c是等差数列,且b, c, d是等差数列,那么a, b, c, d是等差数列,等比数列同理 判断ai-2, ai-1, ai是否是等差(比)数列,能在O( ...

  3. BZOJ1003 物流运输 最短路+DP

    1003: [ZJOI2006]物流运输 Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条 ...

  4. 动态规划——线性dp

    我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...

  5. hdu 4352 数位dp + 状态压缩

    XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. DP&图论 DAY 3 下午 考试

    Problem AProblem Description有一天 Tarzan 写了一篇文章,我们发现这文章当中一共出现了 n 个汉字,其中第 i 个汉字出现了 ai 次,因为 Tarzan 不希望文章 ...

  7. [GodLove]Wine93 Tarining Round #8

    比赛链接: http://vjudge.net/contest/view.action?cid=47644#overview 比赛来源: 2012 ACM/ICPC Asia Regional Tia ...

  8. [GodLove]Wine93 Tarining Round #7

    比赛链接: http://vjudge.net/contest/view.action?cid=47643#overview 比赛来源: 2012 ACM/ICPC Asia Regional Han ...

  9. BZOJ 2466: [中山市选2009]树

    Sol 树形DP. 听说有非常神奇的高斯消元的做法...orz... 然而我只会 \(O(n)\) 的树形DP. 首先一个点的状态只于他的父节点和子树有关,跟他 子树的子树 和 父亲的父亲 都没有任何 ...

  10. [GodLove]Wine93 Tarining Round #3

    比赛链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=44857#overview 题目来源: ZOJ Monthly, July 2 ...

随机推荐

  1. 春节过后就是金三银四求职季,分享几个Java面试妙招,轻松搞定HR!

    春节过后就是金三银四,分享几个Java面试妙招,轻松搞定HR! 2020年了,先祝大家新年快乐! 今年IT职位依然相当热门,特别是Java开发岗位.软件开发人才在今年将有大量的就业机会.春节过后,金三 ...

  2. python全栈学习 day03

    换行符: \n 制表符: \t 字符串截取:顾头不顾尾 s[首:尾:步长] 首--->尾走向 和 步长方向一致 s[0:4:2] s[4:0:-2] a = "qwertyui&quo ...

  3. 【Android休眠】之Android休眠机制

    一.休眠概述 休眠,简而言之就是设备在不需要工作的时候把一些部件.外设关掉(掉电或让它进入低功耗模式). 为什么要休眠呢?一言以蔽之:省电. 休眠分主动休眠和被动休眠.主动休眠:比如我电脑不用了,就通 ...

  4. Linux查看系统硬件信息命令

    Linux查看系统硬件信息命令 查看磁盘类型(是否SSD) cat /sys/block/sda/queue/rotational code:0 SSD盘 code:1 SATA盘 查看物理CPU个数 ...

  5. CF1093E Intersection of Permutations [分块 +bitset]

    大家好, 我非常喜欢暴力数据结构, 于是就用分块A了此题 分块题,考虑前缀和 \(b_i\) 表示 bitset 即 \(0\) ~ $i $ 出现过的数字,然后考虑直接暴力复制块然后前缀和,修改也很 ...

  6. 曼孚科技:AI算法领域常用的39个术语(下)

    算法是人工智能(AI)核心领域之一. 本文整理了算法领域常用的39个术语,希望可以帮助大家更好地理解这门学科. 本文为下半部分,上半部分见本账号上一篇文章. 19.迁移学习(Transfer Lear ...

  7. Goland 2019下载和安装(带破解补丁和汉化包)

    Goland 简介 Goland 是由 JetBrains 公司开发的一个新的商业 IDE,旨在为 Go 开发者提供的一个符合人体工程学的新的商业 IDE.Goland 整合了 IntelliJ 平台 ...

  8. Web简单小结

    一.HTML DOM 使 JavaScript 有能力对 HTML 事件做出反应:<h1 onclick="this.innerHTML='你点我干啥'">请点击这里& ...

  9. POI导出PPT

    1.null <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> <dependency> <g ...

  10. ubuntu 16.04.1上安装并使用vsftpd

    1.安装vsftpd软件 sudo apt-get install vsftpd 2.新建文件 sudo vim /etc/vsftpd.user_list 用于记录用户名 3. 修改sudo vim ...