HDU 2577 How to Type (线性dp)

本文探讨了一个关于最小按键次数的问题,利用动态规划(DP)算法解决实际问题,详细介绍了输入输出规范及样例解析,展示了如何通过算法优化解决键盘操作问题。


How to Type

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 4616    Accepted Submission(s): 2084

Problem Description
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.
 
Input
The first line is an integer t (t<=100), which is the number of test case in the input file. For each test case, there is only one string which consists of lowercase letter and upper case letter. The length of the string is at most 100.
 
Output
For each test case, you must output the smallest times of typing the key to finish typing this string.
 
Sample Input
  
3 Pirates HDUacm HDUACM
 
Sample Output
  
8 8 8
Hint
The string “Pirates”, can type this way, Shift, p, i, r, a, t, e, s, the answer is 8. The string “HDUacm”, can type this way, Caps lock, h, d, u, Caps lock, a, c, m, the answer is 8 The string "HDUACM", can type this way Caps lock h, d, u, a, c, m, Caps lock, the answer is 8
 
Author
Dellenge
 
Source
HDU 2009-5 Programming Contest

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2577

题目大意:坑比题,给一些有大小写组成的字符串,问用键盘打出它们的最少按键次数
按键规则:对于每一个小写字母,加上shift可使其变成大写,注意shift不可以一直按着不放,还可以开大写锁Caps lock键,按完这键输入就变成大写,此时再按shift,则打出小写(mac的键盘貌似不是这样),注意每次大写锁,最后必须把它关上

题目分析:知道题以后就很简单了dp[i][0]和dp[i][1]分别表示到第i个字符大写锁关,开着时要按的最少次数,则有4种情况
如果到第i个字符为小写且此时开着大写锁,则它前一个必然是大写,因为如果前一个是小写,当前也是小写,我显然不需要开大写锁
dp[i][1] = dp[i - 1][1] + 2
如果到第i个字符为小写且此时没开大写锁,直接打就行了
dp[i][0] = dp[i - 1][0] + 1
如果到第i个字符为大写且此时开着大写锁,则为前一个开着大写锁的情况加1和前一个没开大写锁的情况加2的最小值,表示开锁
dp[i][1] = min(dp[i - 1][1] + 1, dp[i - 1][0] + 2)
如果到第i个字符为大写且此时没开大写锁,则为前一个没开大写锁的情况加2(按shift)和前一个开着大写锁的情况加2的最小值,表示关锁
dp[i][0] = min(dp[i - 1][0] + 2, dp[i - 1][1] + 2)

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int const MAX = 105;
char s[MAX];
int dp[MAX][2];

bool judge(char ch)
{
    if(ch >= 'A' && ch <= 'Z')
        return true;
    return false;
}

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%s", s + 1);
        int len = strlen(s + 1);
        memset(dp,0, sizeof(dp));
        dp[0][1] =  1;
        for(int i = 1; i <= len; i++)
        {
            if(judge(s[i]))
            {
                dp[i][1] = min(dp[i - 1][1] + 1, dp[i - 1][0] + 2);
                dp[i][0] = min(dp[i - 1][0] + 2, dp[i - 1][1] + 2);
            }
            else
            {
                dp[i][1] = dp[i - 1][1] + 2;
                dp[i][0] = dp[i - 1][0] + 1;
            }
        }
        printf("%d\n", min(dp[len][0], dp[len][1] + 1));
    }
}



c++14 ## 题目描述 最近发现了一种名为 **推箱子蚁** 的新蚂蚁物种。它们因其独特习性而引起了昆虫学家的注意。这些蚂蚁不形成蚁群。相反,个体建造自己的私人巢穴,并将食物(坚果)储存在巢穴中。一个巢穴包含许多由隧道连接的小房间。它们只将房间建造得比坚果稍大一点,仅留下足够空气流通的空间;它们无法进入有坚果的房间。为了节省劳力,隧道非常狭窄,其大小恰好能容纳一颗坚果,因此坚果不能留在隧道中,以便空气流通。 要进入一个有坚果的房间,必须将坚果通过连接它们的隧道推到该房间的任意一个相邻空房间中。如果除了蚂蚁进来的房间外没有其他相邻的空房间,坚果就无法被推开,因此蚂蚁无法进入该房间。 热衷于研究这种蚂蚁的昆虫学家 Myrmink 博士绘制了一个典型巢穴的示意图。该图还显示了哪些房间储存了坚果,以及蚂蚁最初在哪个房间。你的任务是编写一个程序,计算蚂蚁能够到达并进入的房间数量。将一颗坚果推入某个相邻的空房间可能会使一些房间变得无法到达,而选择另一个房间来推入则可能保持这些房间的可达性。可能存在许多这样的选择组合。在这种情况下,应该将所有可能通过一种或多种选择组合到达的房间都计算在内。 你可以假设蚂蚁最初所在的房间没有坚果,并且巢穴中没有循环路径。 ## 输入格式 输入包含单个测试用例,格式如下,代表一个巢穴的示意图。 $$ \begin{aligned} &n \ m \\ &x_1 \ y_1 \\ &\vdots \\ &x_{n-1} \ y_{n-1} \\ &a_1 \\ &\vdots \\ &a_m \end{aligned} $$ 其中,$n$ 和 $m$ 分别是房间和坚果的数量。它们满足 $1 \le n \le 2 \times 10^5$ 且 $0 \le m < n$。房间编号从 $1$ 到 $n$。蚂蚁初始在房间 $1$。 接下来的 $n - 1$ 行中,每行有两个整数 $x_i$ 和 $y_i$ ($1 \le i \le n - 1$),表示一条隧道连接编号为 $x_i$ 和 $y_i$ 的房间。满足 $1 \le x_i \le n$,$1 \le y_i \le n$,且 $x_i \ne y_i$。没有两条隧道连接同一对房间。 剩下的 $m$ 行中,每行有一个整数 $a_k$ ($1 \le k \le m$,$2 \le a_k \le n$),表示编号为 $a_k$ 的房间中有一颗坚果。所有 $a_k$ 的值互不相同。 ## 输出格式 输出应包含一行,一个整数,表示蚂蚁能够到达并进入的房间数量。 ## 输入输出样例 #1 ### 输入 #1 ``` 7 2 1 2 2 3 3 4 4 5 5 6 5 7 2 4 ``` ### 输出 #1 ``` 2 ``` ## 输入输出样例 #2 ### 输入 #2 ``` 8 2 1 2 2 3 3 4 2 5 5 6 6 7 2 8 2 6 ``` ### 输出 #2 ``` 7 ``` ## 输入输出样例 #3 ### 输入 #3 ``` 7 3 1 2 2 3 3 4 3 5 4 6 5 7 2 4 5 ``` ### 输出 #3 ``` 2 ``` ## 输入输出样例 #4 ### 输入 #4 ``` 11 3 1 2 2 3 3 4 2 5 5 6 6 7 7 8 6 9 9 10 6 11 2 3 7 ``` ### 输出 #4 ``` 9 ```
01-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值