「专题训练」Hard problem(Codeforces Round #367 Div. 2 C)
Posted samhx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「专题训练」Hard problem(Codeforces Round #367 Div. 2 C)相关的知识,希望对你有一定的参考价值。
题意与分析
题意:给出(n)个字符串,可以反转任意串,反转每个串都有其对应的花费(c_i)。经过操作后是否能满足字符串(forall i in [1,n] ext{且} i in R_+, str[i]ge str[i-1]),若能输出最小花费,否则输出-1。
分析:经过各种字符串dp血虐,应该会有个直觉:(dp[i])表示前(i)个串的最小花费。但是好像不太够:没有保存反转。因此,在dp中,如果状态不够,那就加维度保存状态。这里就是:我们定义(dp[i][0],dp[i][1])分别保存最后一个的反转状态即可。后面是很经典的套路了。
代码
#include <bits/stdc++.h>
using namespace std;
vector<string> vec, vecr;
array<long long,100005> cost;
array<array<long long,2>, 100005> dp;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
int n; cin>>n;
for(int i=0;i!=n;++i)
cin>>cost[i];
for(int i=0;i!=n;++i)
{
dp[i][0]=dp[i][1]=1e15;
string tmp; cin>>tmp;
vec.emplace_back(tmp);
reverse(tmp.begin(), tmp.end());
vecr.emplace_back(tmp);
}
dp[0][0]=0; dp[0][1]=cost[0];
int i;
for(i=1;i!=n;++i)
{
if(vec[i]>=vec[i-1])
dp[i][0]=dp[i-1][0];
if(vecr[i]>=vec[i-1])
dp[i][1]=dp[i-1][0]+cost[i];
if(vec[i]>=vecr[i-1])
dp[i][0]=min(dp[i][0], dp[i-1][1]);
if(vecr[i]>=vecr[i-1])
dp[i][1]=min(dp[i][1], dp[i-1][1]+cost[i]);
if(dp[i][0]==1e15 && dp[i][1]==1e15) break;
}
if(i==n) cout<<min(dp[n-1][0], dp[n-1][1])<<endl;
else cout<<-1<<endl;
return 0;
}
以上是关于「专题训练」Hard problem(Codeforces Round #367 Div. 2 C)的主要内容,如果未能解决你的问题,请参考以下文章