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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM