简单动态规划,用两个数组分别保存开灯与不开灯状态,该设置很重要,做题之前要考虑全面。
用两个a,b数组分别记录Caps Lock开与关时打印第i个字母的最少操作步骤;
而对于第i个字母的大小写还要分开讨论:
Ch[i]为小写: a[i]=min(a[i-1]+1,b[i-1]+2);不开灯直接字母,开灯则先关灯再按字母,最后保持不开灯; b[i]=min(a[i-1]+2,b[i-1]+2);不开灯则先按字母再开灯,开灯则Shift+字母(比关灯,按字母再开灯节省步数),最后保持开灯;
Ch[i]为大写: a[i]=min(a[i-1]+2,b[i-1]+2); b[i]=min(a[i-1]+2,b[i-1]+1)
最后,b[len-1]++,关灯嘛O(∩_∩)O~
#include <iostream>
#include <string.h>
using namespace std;
const int N = 101;
char str[N];
int a[N], b[N];//a关灯,b开灯
int min(int a, int b)
{
if(a>b)
return b;
else
return a;
}
int main()
{
int t;
cin >> t;
while(t--)
{
memset(str, 0, sizeof(str));
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
cin >> str;
if(isupper(str[0]))
a[0] = 2, b[0] = 2;
else
a[0] = 1, b[0] = 2;
int n = strlen(str);
if(str[0])
for(int i = 1; i < n; i ++)
{
if(isupper(str[i]))
{
a[i] = min(a[i-1] +2, b[i-1] + 2);
b[i] = min(a[i-1] +2, b[i-1] + 1);
}
else
{
a[i] = min(a[i-1] + 1, b[i-1] +2);
b[i] = min(a[i-1] + 2, b[i-1] +2);
}
}
b[n-1]++;
cout << min(a[n-1], b[n-1]) << endl;
}
return 0;
}