题意:

二指输入法定制键盘在 XY 平面上的布局如上图所示,
其中每个大写英文字母都位于某个坐标处,
例如字母 A 位于坐标 (0,0),字母 B 位于坐标 (0,1),字母 P 位于坐标 (2,3) 且字母 Z 位于坐标 (4,1)。
给你一个待输入字符串 word,请你计算并返回在仅使用两根手指的情况下,键入该字符串需要的最小移动总距离。
坐标 (x1,y1) 和 (x2,y2) 之间的距离是 |x1 - x2| + |y1 - y2|。
注意,两根手指的起始位置是零代价的,不计入移动总距离。
你的两根手指的起始位置也不必从首字母或者前两个字母开始。
数据范围:
2 <= word.length <= 300
每个 word[i] 都是一个大写英文字母。
解法:
令d[i][j][k]表示前i个字符,两根手指分别在j和k的最小总代价.
枚举下一个字符用哪根手指,即可进行dp的转移,转移代价为手指移动距离.
code:
class Solution {
public:
#define PI pair<int,int>
int minimumDistance(string s) {
char g[33][33]={
"ABCDEF",
"GHIJKL",
"MNOPQR",
"STUVWX",
"YZ",
};
int dist[33][33]={0};
int d[333][33][33]={0};
int n=s.size();
map<int,PI>mp;
for(int i=0;i<5;i++){
for(int j=0;j<6;j++){
if(!g[i][j])continue;
mp[g[i][j]-'A']={i,j};
}
}
for(int i=0;i<26;i++){
for(int j=0;j<26;j++){
PI x=mp[i],y=mp[j];
dist[i][j]=abs(x.first-y.first)+abs(x.second-y.second);
}
}
for(int i=0;i<=n;i++){
for(int j=0;j<26;j++){
for(int k=0;k<26;k++){
d[i][j][k]=1e9;
}
}
}
for(int j=0;j<26;j++){
for(int k=0;k<26;k++){
d[0][j][k]=0;
}
}
for(int i=0;i<n;i++){
for(int j=0;j<26;j++){
for(int k=0;k<26;k++){
if(d[i][j][k]==1e9)continue;
int nt=s[i]-'A';
d[i+1][nt][k]=min(d[i+1][nt][k],d[i][j][k]+dist[j][nt]);
d[i+1][j][nt]=min(d[i+1][j][nt],d[i][j][k]+dist[k][nt]);
}
}
}
int ans=1e9;
for(int j=0;j<26;j++){
for(int k=0;k<26;k++){
ans=min(ans,d[n][j][k]);
}
}
return ans;
}
};