题意:
就是一共有QWE3个法球,然后存满3个法球按一次R,就可以放出对应的技能,当然一个技能对应3个法球,顺序无所谓。然后当有3个法球的时候,再放一个法球,那么最开始的法球就会消失。现在给你一个技能顺序,问你最少要按多少次键盘。
思考:
刚开始我没看到技能的法球是任意的,直接以为是模拟。发现是任意的之后,这肯定不能模拟了,也不能搜索,只能就是dp,然后发现技能就3个字母所以也就6中状态,所以dp[i][j]代表走到i的j状态的最小操作次数。不同的状态用一下permutation就行了。值得注意的是,per必须是字符是从小到大排序的,当时我以为QWE就是排序的,实际上E明明更小,可能游戏打多了。
代码:
int T,n,m,k;
int va[N];
char s[N];
int dp[N][10];
map<char,string> mp;
int get(string s1,int t1,string s2,int t2)
{
do{
if(--t1==0) break;
}while(next_permutation(s1.begin(),s1.end()));
do{
if(--t2==0) break;
}while(next_permutation(s2.begin(),s2.end()));
char a1 = s1[0],b1 = s1[1],c1 = s1[2];
char a2 = s2[0],b2 = s2[1],c2 = s2[2];
if(a1==a2&&b1==b2&&c1==c2) return 0;
if(b1==a2&&c1==b2) return 1;
if(c1==a2) return 2;
return 3;
}
signed main()
{
IOS;
mp['Y'] = "QQQ";mp['V'] = "QQW";mp['G'] = "QQE";
mp['C'] = "WWW";mp['X'] = "QWW";mp['Z'] = "WWE";
mp['T'] = "EEE";mp['F'] = "QEE";mp['D'] = "WEE";mp['B'] = "QWE";
for(auto t:mp)
{
string now = t.se;
sort(now.begin(),now.end());mp[t.fi] = now;
}
cin>>s+1;n = strlen(s+1);
for(int i=1;i<=n;i++) for(int j=1;j<=6;j++) dp[i][j] = inf;
for(int i=1;i<=6;i++) dp[1][i] = 3;
for(int i=2;i<=n;i++)
{
for(int j=1;j<=6;j++)
{
for(int k=1;k<=6;k++)
dp[i][j] = min(dp[i][j],dp[i-1][k]+get(mp[s[i]],j,mp[s[i-1]],k));
}
}
int minn = inf;
for(int i=1;i<=6;i++) minn = min(minn,dp[n][i]);
cout<<minn+n;
return 0;
}
总结:
多多思考呀。注意细节。