题意:输入一个字符串,要求只能用Caps键和Shift键,问最少的击键次数是多少?
思路:dp[i][2] 表示 输入到第i个字符时Caps亮或者暗的最少步数,dp[i][0] 代表Caps键是暗的,dp[i][1]代表Caps键是亮的。dp方程代码中有解释。
http://acm.hdu.edu.cn/showproblem.php?pid=2577
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define rep(i,a,b) for(int i = a ; i <= b ; i ++)
#define rrep(i,a,b) for(int i = b ; i >= a ; i --)
#define repE(p,u) for(Edge * p = G[u].first ; p ; p = p -> next)
#define cls(a,x) memset(a,x,sizeof(a))
using namespace std;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5;
const int MAXE = 2e5;
typedef long long LL;
int T,n,m,k;
char a[105];
int dp[105][2];
void input() {
scanf("%s",a);
}
void solve() {
int lena = strlen(a);
if(a[0] >= 'a' && a[0] <= 'z') {
dp[0][0] = 1 ; dp[0][1] = 2;
}
else {
dp[0][0] = 2 ; dp[0][1] = 2;
}
rep(i,1,lena-1) {
if(a[i] >= 'a' && a[i] <= 'z') {
dp[i][0] = min(dp[i-1][0]+1,dp[i-1][1]+2);
dp[i][1] = min(dp[i-1][0]+2,dp[i-1][1]+2);
}
else {
dp[i][0] = min(dp[i-1][0]+2,dp[i-1][1]+2);
dp[i][1] = min(dp[i-1][0]+2,dp[i-1][1]+1);
}
}
printf("%d\n",min(dp[lena-1][0],dp[lena-1][1]+1));
}
int main(void) {
scanf("%d",&T);
while(T--) {
input();
solve();
}
return 0;
}