Skip to main content
  1. Posts/

CodeForces-706C Hard problem

·2 mins·

CodeForces-706C Hard problem #

题目大意 #

给定 $n$ 个字符串 $s_1, s_2, …, s_n$ 和反转它们需要的代价 $a_1, a_2, …, a_n$ . 返回把字符串数组修改成按字典序排列的最少代价; 如果不能做到这一点, 返回 $-1$ .

Solution 1 #

对于一个字符串, 我们可以反转, 也可以选择不反转, 根据前一个字符串是否反转, 可以得到相应的代价变化. 代码如下:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll MAXN = 1e15 + 10;
string reverse_string(string s) {
    string res = "";
    for (int i = s.size() - 1; i >= 0; i--) {
        res += s[i];
    }
    return res;
}

int main() {
    int n;
    cin>>n;
    vector<ll> a(n, 0);
    vector<string> s(n), r(n);
    for (int i = 0; i < n; i++) {
        cin>>a[i];
    }
    for (int i = 0; i < n; i++) {
        cin>>s[i];
        r[i] = reverse_string(s[i]);
    }
    vector<vector<ll>> dp(n, vector<ll>(2, MAXN));
    // dp[i][0] 表示 0 - i 个字符串, 第 i 个不反转 合法的最小代价
    dp[0][0] = 0;
    dp[0][1] = a[0];
    for (int i = 1; i < n; i++) {
        if (s[i] >= s[i - 1]) {
            dp[i][0] = min(dp[i][0], dp[i - 1][0]);
        }
        if (s[i] >= r[i - 1]) {
            dp[i][0] = min(dp[i][0], dp[i - 1][1]);
        }
        if (r[i] >= s[i - 1]) {
            dp[i][1] = min(dp[i][1], dp[i - 1][0] + a[i]);
        }
        if (r[i] >= r[i - 1]) {
            dp[i][1] = min(dp[i][1], dp[i - 1][1] + a[i]);
        }
    }
    ll ans = min(dp[n- 1][0], dp[n - 1][1]) == MAXN? -1: min(dp[n- 1][0], dp[n - 1][1]);
    cout<<ans<<endl;
    return 0;
}