hdu 6739 Invoker

北城余情 提交于 2019-11-30 16:32:25

Invoker

Problem Description

在 dota2 中有一个叫做祈求者(Invoker)的英雄,在游戏中他有三个基础技能:冰(Quas),雷(Wex),火(Exort),每施展一个技能就可以获得相应属性的一个法球(element)。

但是祈求者同时最多只能有三个法球,即如果他在有三个法球的状态下又使用了某个法球技能,那么他会获得该法球,并失去之前三个法球中最先获得的一个。

不难得出,祈求者身上的三个法球的**无顺序**组合有 10 种,每一种都对应着一个组合技能:

1. 急速冷却(Cold Snap),无序组合 QQQ,用 Y 表示
2. 幽灵漫步(Ghost Walk),无序组合 QQW,用 V 表示
3. 寒冰之墙(Ice Wall),无序组合 QQE,用 G 表示
4. 电磁脉冲(EMP),无序组合 WWW,用 C 表示
5. 强袭飓风(Tornado),无序组合 QWW,用 X 表示
6. 灵动迅捷(Alacrity),无序组合 WWE,用 Z 表示
7. 阳炎冲击(Sun Strike),无序组合 EEE,用 T 表示
8. 熔炉精灵(Forge Spirit),无序组合 QEE,用 F 表示
9. 混沌陨石(Chaos Meteor),无序组合 WEE,用 D 表示
10. 超震声波(Deafening Blast),无序组合 QWE,用 B 表示

当祈求者拥有三个法球的时候,使用元素祈唤(Invoke)技能,用 R 表示,便可获得当前法球组合所对应的技能,同时原有的三个法球也不会消失,先后顺序的状态也不会改变。

现在给定一个技能序列,你想按照给定的顺序将他们一个一个地祈唤出来,同时你想用最少的按键来达到目标,所以你想知道对于给定的一个技能序列,最少按多少次键才能把他们都祈唤出来。

注意:游戏开始的时候,祈求者是没有任何法球的。

Input

仅一行一个字符串 s,表示技能序列。其中所有字母都是大写,且在 {B,C,D,F,G,T,V,X,Y,Z} 内。

1≤|s|≤105

Output

仅一行一个正整数,表示最少按键次数。

Sample Input

XDTBV

Sample Output

14

Hint

一种按键最少的方案为:QWWREERERWQRQR

 

思路:暴力DP,把当前可行的情况枚举出来,然后跟之前枚举的匹配进行递推。

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<map>
  7 #include<set>
  8 #include<vector>
  9 #include<queue>
 10 #include<list>
 11 #include<stack>
 12 //#include<unordered_map>
 13 using namespace std;
 14 #define ll long long
 15 #define dd cout<<endl
 16 #define lll __int128
 17 const int mod=1e9+7;
 18 const int inf=1e9+7;
 19 
 20 const int maxn=1e6+10;
 21 
 22 int dp[maxn][10];
 23 
 24 int main()
 25 {
 26     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 27     
 28     string str;
 29     
 30     while(cin>>str)
 31     {
 32         memset(dp,0X3f3f3f,sizeof(dp));
 33         
 34         string last[6];
 35         
 36         string now[6];
 37         
 38         for(int i=0;i<str.size();i++)
 39         {
 40             if(str[i]=='Y')
 41             {
 42                 now[0]="QQQ",now[1]="QQQ",now[2]="QQQ";
 43                 now[3]="QQQ",now[4]="QQQ",now[5]="QQQ";
 44             }
 45             else if(str[i]=='V')
 46             {
 47                 now[0]="QQW",now[1]="QWQ",now[2]="QQW";
 48                 now[3]="QWQ",now[4]="WQQ",now[5]="WQQ";
 49             }
 50             else if(str[i]=='G')
 51             {
 52                 now[0]="EQQ",now[1]="EQQ",now[2]="QEQ";
 53                 now[3]="QQE",now[4]="QEQ",now[5]="QQE";
 54             }
 55             else if(str[i]=='C')
 56             {
 57                 now[0]="WWW",now[1]="WWW",now[2]="WWW";
 58                 now[3]="WWW",now[4]="WWW",now[5]="WWW";
 59             }
 60             else if(str[i]=='X')
 61             {
 62                 now[0]="QWW",now[1]="QWW",now[2]="WQW";
 63                 now[3]="WWQ",now[4]="WQW",now[5]="WWQ";
 64             }
 65             else if(str[i]=='Z')
 66             {
 67                 now[0]="EWW",now[1]="EWW",now[2]="WEW";
 68                 now[3]="WWE",now[4]="WEW",now[5]="WWE";
 69             }
 70             else if(str[i]=='T')
 71             {
 72                 now[0]="EEE",now[1]="EEE",now[2]="EEE";
 73                 now[3]="EEE",now[4]="EEE",now[5]="EEE";
 74             }
 75             else if(str[i]=='F')
 76             {
 77                 now[0]="EEQ",now[1]="EQE",now[2]="EEQ";
 78                 now[3]="EQE",now[4]="QEE",now[5]="QEE";
 79             }
 80             else if(str[i]=='D')
 81             {
 82                 now[0]="EEW",now[1]="EWE",now[2]="EEW";
 83                 now[3]="EWE",now[4]="WEE",now[5]="WEE";
 84             }
 85             else if(str[i]=='B')
 86             {
 87                 now[0]="EQW",now[1]="EWQ",now[2]="QEW";
 88                 now[3]="QWE",now[4]="WEQ",now[5]="WQE";
 89             }
 90             
 91             if(i==0)
 92             {
 93                 for(int j=0;j<6;j++)
 94                 {
 95                     dp[i][j]=3;
 96                 }
 97             }
 98             else
 99             {
100                 for(int j=0;j<6;j++)
101                 {
102                     for(int k=0;k<6;k++)
103                     {
104                         string pre=last[k],nxt=now[j];
105                         
106                         int cnt;
107                         
108                         if(pre[0]==nxt[0]&&pre[1]==nxt[1]&&pre[2]==nxt[2])
109                             cnt=3;
110                         else if(pre[1]==nxt[0]&&pre[2]==nxt[1])
111                             cnt=2;
112                         else if(pre[2]==nxt[0])
113                             cnt=1;
114                         else
115                             cnt=0;
116                         
117                         dp[i][j]=min(dp[i][j],dp[i-1][k]+(3-cnt));
118                         
119                     }
120     
121                 }    
122             }
123                 
124             for(int j=0;j<6;j++)
125             {
126                 last[j]=now[j];
127             }
128             
129         }
130         
131         int minn=dp[(int)str.size()-1][0];
132         
133         for(int i=0;i<6;i++)
134         {
135             if(dp[(int)str.size()-1][i]<minn)
136                 minn=dp[(int)str.size()-1][i];
137         }
138         
139         cout<<minn+str.size()<<endl;
140         
141     }
142     
143     return 0;
144 }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!