hdu2577一道很不错的DP

本文介绍了一种求解输入字符串时键盘敲击最小次数的动态规划算法。通过定义状态dp[i][0]和dp[i][1]来分别表示在Caps Lock关闭和打开状态下完成前i个字符所需的最少敲击次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

Pirates have finished developing the typing software. He called Cathy to test his typing software. She is good at thinking. After testing for several days, she finds that if she types a string by some ways, she will type the key at least. But she has a bad habit that if the caps lock is on, she must turn off it, after she finishes typing. Now she wants to know the smallest times of typing the key to finish typing a string.

算法思路

  1. 一个很有趣的题目,感觉可以有很多种方法。
  2. 最直接的方法就是区间DP,因为如果存在两个字符以上的大写字母,开caps lock显然比用shift更加方便,反之,如果存在两个小写字母的话也是同样的情况。
  3. 但是我们可以使用一个更好的方法,dp[i][0]表示打完前i个字符之后caps lock关闭的情况下所用的敲击次数,反之,dp[i][1]则表示的是capslock打开的情况下所用的敲击的次数,这样,很容易建立转移方程,然后得到结果。
  4. 注意的是,最后一定记得关闭capslock.

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;

#define MAXN 105
#define INF 0x3f3f3f3f

char str[MAXN];
int t,len;
int dp[MAXN][2];

bool islow(char c)
{//judge if the char is lowercase
    return (c>='a'&&c<='z');
}

void Solve()
{
    dp[0][0] = 0;
    dp[0][1] = INF;

    int i;

    for(i=0;i<len;i++){
        if(islow(str[i])){
            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);
        }
        else{
            dp[i+1][0] = min(dp[i][0]+2,dp[i][1]+2);
            dp[i+1][1] = min(dp[i][1]+1,dp[i][0]+2);
        }
    }
    printf("%d\n",min(dp[len][0],dp[len][1]+1));
    return;
}

int main()
{
    //freopen("input","r",stdin);
    scanf("%d",&t);

    while(t--){
        scanf("%s",str);
        len = strlen(str);
        Solve();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值