HUST1570 Lazy. Lazy. Laaaaaaaaaaaazy!(动态规划)

Lazy. Lazy. Laaaaaaaaaaaazy!

Time Limit: 1 Sec   Memory Limit: 128 MB
Submissions: 233   Solved: 78

Description

         YangShen is very lazy. One day, he received a typing task from his leader Mr. He, which is non-technical, time-wasteful and as boring as possible. As this,YangShen, the laziest one in the world, want to know an easy way to finish the typing task.
         The key-board that Mr. He provided is a little similar with the key-board that we are familiar with. There is one SHIFT, one CAPS LOCK and some otherNORMAL keys on the key-board, each normal key can input two different chars, one is when the CAPS LOCK is on, another is when the CAPS LOCK is off. It will toggle the input char when pressing SHIFT while input with a NORMAL key. The initial state of CAPS LOCK is off.
         Lazy YangShen want to know the minimum times that he must pressing the keys.

Input

    multiple case, please process to EOF.
    In each case, there are three strings separated by single space. the first, which is the chars input by NORMAL keys when CAPS LOCK is on; the second, which is the chars input by NORMAL keys when CAPS LOCK is off; the third is the text content that Mr. He ask YangShen to typing.
    The length of each string are all smaller than 1001.
    The chars in first string are always different from each other.
    The chars in second string are always different from each other.
    There is no common char between first and second strings.
    The chars in third string are always in the first string or in the second string.

Output

    Print the minimum times YangShen must pressing the keys. 

Sample Input

abc def defabc
abc def abcdef

Sample Output

7
8

HINT

If you use SHIFT to input a char, the times of pressing SHIFT is always count by 1 whether you leave SHIFT up or not.

 

题目大意:给定3个字符串,第一串每个字符全部是大写,第二串每个字符全部是小写,求的输出第三个字符串所需最少的按键,给定了CAPS LOCK(大写锁定)SHIFT(上档键)两个按钮

思路:动态规划,设dp[i][0]表示到第i个字符输出后,并且最后是小写输出时需要的最少的按键;dp[i][1]表示到第i个字符输出后,并且最后是大写输出时需要的最少的按键。

则动态转移方程是:如果当前字符是小写输出的字母,则

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);  //第一个加2,是先按CAPS LOCK,再按字母按钮;第二个加2是按住SHIFT和字母按钮

如果当前字母是大写输出的字母,则

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);

初始条件是:

dp[0][0]=0;
dp[0][1]=1; //因为初始是小写,如果要变成大写,需要先按一下CAPS LOCK

代码如下:

View Code
 1 # include<stdio.h>
 2  # include<string.h>
 3  # include<map>
 4  # include<iostream>
 5  using namespace std;
 6  map<char,int>f;        //用来记录大、小写字母
 7  int dp[1010][2];
 8  char s1[1010],s2[1010],s[1010];    
 9      //这些数组的大小都是1000,不要想当然的以为是26个字母,所以大小为26
10  int min(int a,int b){
11      return a<b?a:b;
12  }
13  int main(){
14      int len,i;
15      while(scanf("%s%s%s",s1,s2,s)!=EOF){
16          f.clear();
17          len=strlen(s1);
18          for(i=0;i<len;i++)
19              f[s1[i]-'a']=1;
20          //如果是大写字母标记为1
21          len=strlen(s2);
22          for(i=0;i<len;i++)
23              f[s2[i]-'a']=0;
24          //如果是大写字母标记为0
25          len=strlen(s);
26          dp[0][0]=0;
27          dp[0][1]=1;
28          for(i=1;i<=len;i++){
29              if(!f[s[i-1]-'a']){            
30                  dp[i][0] = min(dp[i-1][0] +1, dp[i-1][1] + 2);
31                  dp[i][1] = min(dp[i-1][0] +2, dp[i-1][1] + 2);
32              }
33              else{
34                  dp[i][0] = min(dp[i-1][0] +2, dp[i-1][1] + 2);
35                  dp[i][1] = min(dp[i-1][0] +2, dp[i-1][1] + 1);
36              }
37          }
38          printf("%d\n",min(dp[len][0],dp[len][1]));
39      }
40      return 0;
41  }

 

 

你可能感兴趣的:(动态规划)