题意:给出n个字符串,以及翻转第i个字符串所用的能量c[i],通过翻转这些字符串使第i个字符串大于第i-1个字符串,求所用的最小能量。
不知道字符串的长度,没法开数组,可以用STL里面的string .
DP 求解上一个状态到达该状态的最小值。
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<iostream>
#define INF 1e15
#define MAX 100100
using namespace std;
string str[MAX][2];//原来还可以这样用,长见识了。
__int64 dp[MAX][2];
__int64 c[MAX];
string rep(string s)
{
string s1=s;
int i;
int len=s1.length();
for(i=0;i<len/2;i++)
swap(s1[i],s1[len-i-1]);
return s1;
}
int main()
{
int n,i;
while(scanf("%d",&n)!=EOF)
{
for(i=0;i<n;i++)
scanf("%I64d",&c[i]);
for(i=0;i<n;i++)
{
cin>>str[i][0];
str[i][1]=rep(str[i][0]);
}
for(i=0;i<n;i++)
{
dp[i][0]=INF;
dp[i][1]=INF;
}
dp[0][0]=0;
dp[0][1]=c[0];
for(i=1;i<n;i++)
{
if(str[i][0]>=str[i-1][0])
dp[i][0]=dp[i-1][0];
if(str[i][1]>=str[i-1][0])
dp[i][1]=dp[i-1][0]+c[i];
if(str[i][0]>=str[i-1][1])
dp[i][0]=min(dp[i][0],dp[i-1][1]);
if(str[i][1]>=str[i-1][1])
dp[i][1]=min(dp[i][1],dp[i-1][1]+c[i]);
if(dp[i][0]==INF&&dp[i][1]==INF)
break;
}
if(i==n)
{
printf("%I64d\n",min(dp[n-1][0],dp[n-1][1]));
}
else
printf("-1\n");
}
return 0;
}