#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
char dict[10][6][4]= { //本题的状态与每个组合技能的顺序有关
{"QQQ","QQQ","QQQ","QQQ","QQQ","QQQ"}, //直接枚举每个组合技能的顺序
{"QQW","QWQ","QQW","QWQ","WQQ","WQQ"},
{"QQE","QEQ","QQE","QEQ","EQQ","EQQ"},
{"WWW","WWW","WWW","WWW","WWW","WWW"},
{"QWW","QWW","WQW","WWQ","WQW","WWQ"},
{"WWE","WEW","WWE","WEW","EWW","EWW"},
{"EEE","EEE","EEE","EEE","EEE","EEE"},
{"QEE","QEE","EQE","EEQ","EQE","EEQ"},
{"WEE","WEE","EWE","EEW","EWE","EEW"},
{"QWE","QEW","WQE","WEQ","EQW","EWQ"}
};
int dp[N][10];
int cal(int a,int b,int x,int y) { //a表示前一个状态(第a个状态) a x表示第a个组合技第x种顺序
//计算前后两种状态组合技需要多按几次按键
if(dict[a][x][0]==dict[b][y][0] && dict[a][x][1] == dict[b][y][1] && dict[a][x][2]==dict[b][y][2])
return 0;
if(dict[a][x][1]==dict[b][y][0] && dict[a][x][2] == dict[b][y][1])
return 1;
if(dict[a][x][2]== dict[b][y][0])
return 2;
return 3;
}
map<char,int>mp;
int st[N];
int main() {
string s;
mp['Y']=0;
mp['V']=1;
mp['G']=2;
mp['C']=3;
mp['X']=4;
mp['Z']=5;
mp['T']=6;
mp['F']=7;
mp['D']=8;
mp['B']=9;
while(cin>>s) {
int ans=2147483647;
int cc=0;
for(int i=0; i<s.length(); i++) {//若出现XXVV的情况 即前一个技能和本次技能一样则只需按一次R即可 把他处理成XV
if(cc>=1&&s[i]==s[i-1])
continue;
else {
// t+=s[i];
st[cc]=mp[s[i]];
cc++;
}
}
// cout<<t<<"\n";
//dp[i][j]的含义是 第i个组合技用了第j种方案的顺序
for(int i=0; i<6; i++) //该开始第一种方案都是直接需要三次按键来完成
dp[0][i]=3;
for(int i=1; i<cc; i++) {
for(int j=0; j<6; j++) {
dp[i][j]=2147483647;
for(int k=0; k<6; k++) {
dp[i][j]=min(dp[i][j],dp[i-1][k]+cal(st[i-1],st[i],k,j));//枚举第i-1个状态的第k个方案的顺序操作 到第i个状态
//第j个方案的操作数
}
}
}
for(int i=0; i<6; i++)//找到最优解
ans=min(ans,dp[cc-1][i]);
cout<<ans+s.length()<<"\n";//每次组合技都需要按一次R 所以直接加上s的长度
}
}
参考了这位大佬的博客:https://blog.youkuaiyun.com/qq_43461168/article/details/101210999