codeforce 367dev2_c dp

时间:2023-03-09 16:42:39
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\n",ans);
}
return 0;
}