题意:给你一个字符,有大写小写,你模拟键盘打字母的操作,可以shirft变换当前字母,可以开CapsLock灯,最后需要关掉。
因为有两个操作,需要两个维度表示状态转移。
定义:二维 dp[i ][2] ,前i个字母对应当前是 0,1操作 的最小操作。
所以有对应的状态转移方程:(见代码)
有一个细节写错了,dp[i][1]=min(…,dp[i-1][1]+2) 而不是3,这里意思是当前大写灯开了,需要打小写字母之后转态大写灯还是开的,我错误想法是关掉大写灯,写小写字母,再打开,三步,正确是,shift +字母,两步、、、、、
#include <fstream>
#include <iostream>
#include <string>
#include <complex>
#include <math.h>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stdio.h>
#include <stack>
#include <algorithm>
#include <list>
#include <ctime>
#include <memory.h>
#include <ctime>
#include <assert.h>
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define eps 1e-8
#define M_PI 3.141592653589793
typedef long long ll;
const ll mod=1000000007;
const int inf=99999999;
ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
using namespace std;
int dp[110][2];
string s;
int main()
{
int n;cin>>n;
while(n--){
cin>>s;
int len=s.size();
memset(dp,0,sizeof(dp));
dp[0][1]=1;
for(int i=0;i<len;i++){
if(s[i]>='A'&&s[i]<='Z'){
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);
}
else if(s[i]>='a'&&s[i]<='z'){
dp[i+1][0]=min(dp[i][0]+1,dp[i][1]+2);
dp[i+1][1]=min(dp[i][0]+2,dp[i][1]+2);//
}
}
dp[len][1]++;
/*
for(int i=0;i<=len;i++){
for(int j=0;j<2;j++){
cout<<dp[i][j]<<" ";
}
cout<<endl;
}*/
cout<<min(dp[len][0],dp[len][1])<<endl;
}
}