题目链接:点击打开链接
这个题比较有意思。大意是一个人要打一些字,他有两种方法,一种是Shift+字母,一种是Capslock之后打字母,这两种可以灵活应用,问打一段单词最少的按键次数。。这个题第一反应是搜索,写了个递归然后TLE。后来DISCUSS中得到了DP的思路。dp数组用二维,其中第二维表示capslock的开与关(1开0关),第一位是欲打的第i个字母,不断比较按capslock的方式和按shift的方式,(别忘了每一步都要得出结果,中间状态也要存储起来)最后得出哪个最短,还有线段树/树状数组方法,感觉过于繁琐了。
千万别忘了最后还得使capslock保持熄灭状态!
#include <iostream>
#include <string>
#include <cstring>
#include <ctype.h>
using namespace std;
int min(int a,int b)
{
return a<b?a:b;
}
int dp[105][2];
int main()
{
int testcase;
cin>>testcase;
while(testcase--)
{
memset(dp,0,sizeof(0));
dp[0][1]=1; //不要忘了设定初始值
string tar;
cin>>tar;
int strlength=tar.size();
for(int i=0;i<strlength;i++)
{
if(islower(tar[i]))
{
dp[i+1][0]=min(dp[i][0]+1,dp[i][1]+2); //例:第一个是指在capslock关闭的情况下输入小写字母,只需按一下,+1
//例:第二个是指在capslock打开的情况下输入小写字母,capslock->字母,+2
dp[i+1][1]=min(dp[i][0]+2,dp[i][1]+2); //这里第一个是capslock->字母,第二个是shift+字母,终态永远是左边,故+2
}
else
{
dp[i+1][0]=min(dp[i][0]+2,dp[i][1]+2);
dp[i+1][1]=min(dp[i][0]+2,dp[i][1]+1);
}
}
if(dp[strlength][0]<(dp[strlength][1]+1))
{
cout<<dp[strlength][0]<<endl;
}
else
{
cout<<dp[strlength][1]+1<<endl;
}
}
}