您的位置:首页 > 其它

Codeforces Round #367 (Div. 2)-C - Hard problem-DP

2016-08-12 03:00 411 查看
题意:给字符串n个,

能否通过逆序某些字符串,使得最后整体字典序递增。

每个字符串翻转需要花费,输出最小花费使得 整体字典序递增

dp[i][0]表示第i个字符串选择不翻转的花费

dp[i]【1】表示要翻转的花费

简单dp一下就好了。。最后答案判断是否超过IN

if (ss[i]>=ss[i-1])
dp[i][0]=min(dp[i][0],dp[i-1][0]);

if (rev_ss[i]>=ss[i-1])
dp[i][1]=min(dp[i][1],c[i]+dp[i-1][0]);

if (ss[i]>=rev_ss[i-1])
dp[i][0]=min(dp[i][0],dp[i-1][1;

if (rev_ss[i]>=rev_ss[i-1])
dp[i][1]=min(dp[i][1],c[i]+dp[i-1][1]);

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;

const double pi=acos(-1.0);
double eps=0.000001;
typedef long long ll;

string ss[100123];
string rev_ss[100123];
ll c[100123];
ll dp[100123][2];
char tmp[100123];
char tt[100123];
int ok[100123][2];
int main()
{
int n;
cin>>n;
for (int i=1; i<=n; i++) scanf("%lld",&c[i]);
for (int i=1; i<=n; i++)
{
scanf("%s",tmp);
ss[i]=tmp;
int len=strlen(tmp);
for (int j=0; j<len; j++)
tt[j]=tmp[len-j-1];
tt[len]=0;
rev_ss[i]=tt;
}

for (int i=1; i<=n; i++)
dp[i][0]=dp[i][1]=1e16;

dp[0][0]=dp[0][1]=0;
ok[0][1]
=ok[0][0]=1;
for (int i=1; i<=n; i++)
{
if (ok[i-1][0])
{
if (ss[i]>=ss[i-1])
dp[i][0]=min(dp[i][0],dp[i-1][0]),ok[i][0]=1;

if (rev_ss[i]>=ss[i-1])
dp[i][1]=min(dp[i][1],c[i]+dp[i-1][0]),ok[i][1]=1;

}
if (ok[i-1][1])
{
if (ss[i]>=rev_ss[i-1])
dp[i][0]=min(dp[i][0],dp[i-1][1]),ok[i][0]=1;

if (rev_ss[i]>=rev_ss[i-1])
dp[i][1]=min(dp[i][1],c[i]+dp[i-1][1]),ok[i][1]=1;
}

}

if (ok
[0]==0&&
ok
[1]==0)
{
printf("-1\n");
return 0;
}
printf("%lld\n",min(dp
[0],dp
[1]));

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: