「专题训练」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)的主要内容,如果未能解决你的问题,请参考以下文章

专题训练之LCA

HDU 4403 A very hard Aoshu problem(DFS)

A very hard Aoshu problem

如何证明NP-Hard Problems

218. The Skyline Problem-Hard

CF367C. Hard problem