题目链接:http://218.28.220.249:50015/JudgeOnline/problem.php?id=1264
1264: 某科学的打麻将
时间限制: 1 秒 内存限制: 64 MB提交: 74 解决: 11
提交 状态
题目描述
过年打麻将果然是一项必备技能(雾),打麻将的起手式是整理好自己手中的牌,现在你有十三张牌(只可能出现一万到九万,一筒到九筒,一条到九条),你要把这些牌整理好,使得相同花色的牌必须在连续的唯一一段(即所有的"万"要放在一起,所有的"条"要放在一起,所有的"筒"要放在一起。),每段内牌是按照从小到大的顺序排列(“万”,“条”,“筒”的顺序没有要求)。你每次只能将当前牌中的任意一张牌放到最左边或者最右边。请问最少经过多少次可以使得牌被整理好。
一万到九万,用数字1-9表示
一筒到九筒,用小写字母a-i表示
一条到九条,用大写字母A-I 表示
输入
第一行 一个数字T代表数据组数(T<=10000)
接下来每行 13个字符 代表初始的牌
输出
T行每行一个数字,代表答案
样例输入
1
3abcABBDEFG11
样例输出
1
提示
样例解释
我们把3 放到 最右边就好了
abcABBDEFG113
假如字符串的初始状态为s:aabcbdaec
为了清晰没有写全,结束状态t:aaabbccde
匹配的原则是:在s中抽取一部分字符按其位置的顺序排成字符串,这个字符串是t的子串,假设我们选取aabcbdaec 组成aabbc,aabbc就是t的一个子串,而s变成t的其中一种方式就是将其余的字符按顺序移动到相应的位置,对于s是将a移动到左边,cde移动到右边,这样做的原理是规则要求只能将一个字符移到左边或者右边,没有移动过的字符(红色)相对位置是不变的,并且红色字符最后会在中间组合在一起,而周围的字符可以随意组合并且组合方式与移动次数无关,可以直接算出移动次数。这样就要求红色字符串必须为t的子串,而我们需要求可匹配的最大子串长度。
注意这里有误导,就是t是按大小排序的,但不是求最长上升子序列,因为最长上升子序列不一定是子串,如上文最长上升子序列aabcde,但不是子串。
具体实现dp就好了,dp[i][j]表示s的前i个和t的前j个字符最大匹配长度,递推公式:dp[i][j]=dp[i-1][j-1](s[i]=t[j])||dp[i-1][j](s[i]!=t[j])
//
// main.cpp
// 某科学的打麻将2
//
// Created by teddywang on 2017/4/27.
// Copyright © 2017年 teddywang. All rights reserved.
//
#include <iostream>
#include<cstring>
#include<cstring>
#include<algorithm>
using namespace std;
int T;
char s[14];
char tnumb[14],tlow[14],tupp[14];
int len=13;
int ln,ll,lu;
int ans;
char buf[14];
int dp[20][20];
int solve()
{
int maxn=0;
memset(dp, 0, sizeof(dp));
for(int i=0;i<len;i++)
{
for(int j=0;j<len;j++)
{
if(s[i]==buf[j])
{
if(i==0||j==0) dp[i][j]=1;
else dp[i][j]=dp[i-1][j-1]+1;
}
else
{
if(i==0) dp[i][j]=0;
else dp[i][j]=dp[i-1][j];
}
maxn=max(maxn,dp[i][j]);
}
}
return len-maxn;
}
int main()
{
//freopen("/Users/apple/Desktop/textin.txt","r",stdin);
//freopen("/Users/apple/Desktop/textioon3.txt","w",stdout);
cin>>T;
while(T--)
{
scanf("%s",s);
ln=ll=lu=0;
memset(tlow,0,sizeof(tlow));
memset(tupp,0,sizeof(tupp));
memset(tnumb,0,sizeof(tnumb));
len=strlen(s);
for(int i=0;i<len;i++)
{
if(s[i]<='9'&&s[i]>='0')
tnumb[ln++]=s[i];
else if(s[i]<='i'&&s[i]>='a')
tlow[ll++]=s[i];
else if(s[i]<='I'&&s[i]>='A')
tupp[lu++]=s[i];
}
sort(tupp,tupp+lu);
sort(tlow,tlow+ll);
sort(tnumb,tnumb+ln);
memset(buf,0,sizeof(buf));
strcat(buf,tupp);strcat(buf,tlow);strcat(buf,tnumb);
ans=solve();
memset(buf,0,sizeof(buf));
strcat(buf,tupp);strcat(buf,tnumb);strcat(buf,tlow);
ans=min(ans,solve());
memset(buf,0,sizeof(buf));
strcat(buf,tlow);strcat(buf,tupp);strcat(buf,tnumb);
ans=min(ans,solve());
memset(buf,0,sizeof(buf));
strcat(buf,tlow);strcat(buf,tnumb);strcat(buf,tupp);
ans=min(ans,solve());
memset(buf,0,sizeof(buf));
strcat(buf,tnumb);strcat(buf,tlow);strcat(buf,tupp);
ans=min(ans,solve());
memset(buf,0,sizeof(buf));
strcat(buf,tnumb);strcat(buf,tupp);strcat(buf,tlow);
ans=min(ans,solve());
printf("%d\n",ans);
}
}