鏈接[http://codeforces.com/group/1EzrFFyOc0/contest/706/problem/C]
題意:
他希望它們按詞典順序排序(就像字典中那樣),但他不允許交換其中的任何一個。
唯一允許他做的操作是將其中的任何一個反轉(第一個字符變成最后一個,
第二個字符變成最后一個,以此類推)。
思路;
DP,不斷更新花費的值,並且判斷是否可以滿足字典序排序。
dp[i][0]表示,表示排到第i+1個字符串,不需要反轉需要的花費,dp[i][0]表示排到第i+1個字符串,需要反轉需要的花費。
代碼
#include<bits/stdc++.h>
using namespace std;
#define ll long long
string reverse(string s)
{
string res=s;
int i,len=res.length();
for(i=0;i<len/2;++i)
swap(res[i],res[len-1-i]);
return res;
}
string s[100005][2];//二維字符串數組
ll dp[100005][2];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
//map<string,int> m;
int n,i;
ll a[100005];
//freopen("in.txt","r",stdin);
while(cin>>n){
for(i=0;i<n;i++)
cin>>a[i];
for(i=0;i<n;++i)
dp[i][0]=dp[i][1]=9999999999999999;
dp[0][0]=0,dp[0][1]=a[0];
for(i=0;i<n;++i)
{
cin>>s[i][0];
s[i][1]=reverse(s[i][0]);
}
for(i=1;i<n;i++)
{
if(s[i][0]>=s[i-1][0])
dp[i][0]=dp[i-1][0];//二者都不需要反轉
if(s[i][1]>=s[i-1][0])
dp[i][1]=dp[i-1][0]+a[i];//后者需要反轉就dp[i-1][0]+a[i]
if(s[i][0]>=s[i-1][1])
dp[i][0]=min(dp[i][0],dp[i-1][1]);//前者需要反轉,因為開始初始化一個很大的數所以要比較
if(s[i][1]>=s[i-1][1])
dp[i][1]=min(dp[i][1],dp[i-1][1]+a[i]);//二者都需要反轉,且初始化為很大,需要比較
if(dp[i][0]==9999999999999999&&dp[i][1]==9999999999999999)
//如果不滿足字典序排序,就退出DP
break;
}
ll ans=min(dp[n-1][0],dp[n-1][1]);
if(i>=n) cout<<ans<<endl;
else cout<<-1<<endl;
}
return 0;
}