CF367C. Hard problem

Posted mch5201314

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF367C. Hard problem相关的知识,希望对你有一定的参考价值。

链接[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;
}



以上是关于CF367C. Hard problem的主要内容,如果未能解决你的问题,请参考以下文章

CF660C Hard Process

CF706C Hard problem (状态机dp)

CF #edu 11 C. Hard Process

CF1096D Easy Problem [dp]

Codeforces 1203F2 Complete the Projects (hard version)

codeforces cf educatonal round 57(div2) D. Easy Problem