题意:给你一串字符串,只包含大写字母和小写字母,问打出这串字符最少要按多少次键。但如果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 }