How to Type HDU 2557

 

题意:给你一串字符串,只包含大写字母和小写字母,问打出这串字符最少要按多少次键。但如果Caps Lock键最后是打开的一定要把Caps Lock键关掉。

 

题解:首先你要知道1.当Caps Lock键关闭的时候打出一个大写字母可以有两种方法:1.按下Caps Lock键再按字母键 2.按Shift键并按字母键。2.当Caps Lock键打开的时候打出一个小写字母也有两种方法:1.按下Caps Lock键,再按字母键 2.按Shift键并按字母键。

         题目涉及Caps Lock键的两种状态:关闭和打开。因此可以开一个二维数组,一维表示Caps Lock键关闭,另一维表示Caps Lock键打开。但这里也可以开两个一维数组on[]和off[]分别表示Caps Lock键的两种状态。(此题和算法导论的动态规划章节中的一题双线作业调度类似,那一题也是这样的做法)

状态转移方程:

1             if(s[i]>='A'&&s[i]<='Z') {//如果是大写字母
2                 on[i]=min(on[i-1],off[i-1]+1)+1;//从on状态转移到on状态不需要按任何键,直接按字母键即可,从off状态转移到on状态的最少步数是:先按Caps Lock键再按字母键,所以是off[i-1]+1+1;
3                 off[i]=min(on[i-1]+1,off[i-1]+1)+1;//同理~~~
4             }
5             else {//如果是小写字母
6                 on[i]=min(on[i-1]+1,off[i-1]+1)+1;//在这种情况下从on状态转移到on状态的最小步数是先按Shift键并按字母键,从off状态转移到on状态的最小步数是先按字母键再按Caps Lock键,所以是off[i-1]+1+1;
7                 off[i]=min(on[i-1]+1,off[i-1])+1;
8             }

 

AC代码:

View Code
 1 #include<iostream>
 2 #include<cmath>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int N=105;
 7 int on[N],off[N];
 8 char s[N];
 9 int main()
10 {
11     int T,len;
12     cin>>T;
13     while(T--){
14         cin>>s;
15         len=strlen(s);
16         if(s[0]>='A'&&s[0]<='Z'){
17             on[0]=2;off[0]=2;
18         }
19         else{
20             on[0]=2;off[0]=1;
21         }
22         for(int i=1;i<len;i++){
23             if(s[i]>='A'&&s[i]<='Z') {
24                 on[i]=min(on[i-1],off[i-1]+1)+1;
25                 off[i]=min(on[i-1]+1,off[i-1]+1)+1;
26             }
27             else {
28                 on[i]=min(on[i-1]+1,off[i-1]+1)+1;
29                 off[i]=min(on[i-1]+1,off[i-1])+1;
30             }
31         }
32         cout<<min(on[len-1]+1,off[len-1])<<endl;
33     }
34     return 0;
35 }

 

 

 

posted on 2012-09-21 16:27  Acmer_Roney  阅读(337)  评论(0编辑  收藏  举报

导航