codeforce 367dev2_c dp

codeforce 367dev2_c dp

标签: dp


题意: 你可以通过反转任意字符串,使得所给的所有字符串排列顺序为字典序,每次反转都有一定的代价,问你最小的代价
题解:水水的dp。。。仔细想想就有了,一个位置要么反转要么就不反转。。。保证在满足条件时候转移
扔个代码:

#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
#define ll long long
const int N = 100010;
const ll INF = 4557430888798830399LL;
ll dp[N][2];
ll c[N];
using namespace std;
int main()
{
    string s[N];
    int n;
    while(~scanf("%d",&n))
    {
        for(int i = 0; i < n; i++) {
            scanf("%I64d",&c[i]);
            dp[i][0] = dp[i][1] = INF;
        }
        for(int i = 0; i < n; i++) cin>>s[i];
        dp[0][0] = 0;
        dp[0][1] = c[0];
        for(int i = 1; i < n; i++){
            string tm1 = s[i-1];
            string tm2 = s[i];
            reverse(tm1.begin(),tm1.end());
            reverse(tm2.begin(),tm2.end());
            if(dp[i-1][0]!=INF){
                if(s[i-1]<=s[i]) dp[i][0] = min(dp[i][0],dp[i-1][0]);
                if(s[i-1]<=tm2) dp[i][1] = min(dp[i][1],dp[i-1][0]+c[i]);
            }
            if(dp[i-1][1]!=INF){
                if(tm1<=s[i]) dp[i][0] = min(dp[i][0],dp[i-1][1]);
                if(tm1<=tm2) dp[i][1] = min(dp[i][1],dp[i-1][1]+c[i]);
            }
        }
        ll ans = min(dp[n-1][0],dp[n-1][1]);
        if(ans == INF) puts("-1");
        else printf("%I64d
",ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/shanyr/p/5957499.html