题解 - CF706C
作者:互联网
动态规划吧,不难,被坑了一下,一定不要直接用memset给dp赋0X7F,因为memset按位初始化,所以可能导致有的地方数值不够大。
好吧,我几乎不懂。。。可以的话去学一下memset赋值原理吧。
/*
对于正解状态,第dp[i][0/1]分别表示到达第i个位置时的最少energy。If both dp[i][0] and dp[i][1] 对应的字符串都比dp[i+1][0/1]的要大,则输出-1。
dp[i][0]表示不旋转,dp[i][1]表示旋转。
dp[i][0] = min(dp[i-1][0],dp[i-1][1]) + c[i](if(check(dp[i-1][0/1] both == true)//It's Wrong.
同理可得dp[i][1]。
*/
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define MAXN 100010
#define INF 1e18
//注意INF不可以用0X7F!!!0X7F对于memset虽然够大(因为memste是用按字节赋值的。。。)
int n;
long long eng[MAXN],dp[MAXN][2];
string str[MAXN];
bool check(int a, bool x,bool y)
{//用于比较编号为a-1的字符串在X状态下是否比编号为a的字符串在y状态下要小。
int i = 0;
string stra = str[a-1],strb = str[a];
if(x)reverse(stra.begin(),stra.end());
if(y)reverse(strb.begin(),strb.end());
//while(stra[i] == strb[i] && i <= min(stra.length(),strb.length()))i++;
// cout << strb[i] << " " << stra[i] << endl;
if(strb >= stra)return 1;
return 0;
}
int main()
{
cin >> n;
for(int i = 1; i <= n; ++i)cin >> eng[i];
for(int i = 1; i <= n; ++i)cin >> str[i];
for(int i = 1; i <= n; ++i)dp[i][0] = dp[i][1] = INF;
bool flag = 0;
dp[1][0] = 0,dp[1][1] = eng[1];
for(int i = 2; i <= n; ++i)
{
flag = 0;
if(check(i,0,0) && dp[i-1][0] != INF)dp[i][0] = dp[i-1][0],flag = 1;
if(check(i,0,1) && dp[i-1][0] != INF)dp[i][1] = dp[i-1][0] + eng[i],flag = 1;
if(check(i,1,0) && dp[i-1][1] != INF)dp[i][0] = min(dp[i][0],dp[i-1][1]),flag = 1;
if(check(i,1,1) && dp[i-1][1] != INF)dp[i][1] = min(dp[i][1],dp[i-1][1] + eng[i]),flag = 1;
if(!flag){cout << -1 << endl;return 0;}
}
// cout << (check(2,0,0) && dp[1][0] != INF) << endl;
//字符串比较 ,abc<abcd acb > abcd
//for(int i = 1; i <= n; ++i)cout << dp[i][0] << " " << dp[i][1] << endl;
cout << min(dp[n][0],dp[n][1]) << endl;
return 0;
}
标签:CF706C,int,题解,memset,MAXN,str,stra,dp 来源: https://www.cnblogs.com/Edge-coordinates/p/15678712.html