[关闭]
@xunuo 2017-03-24T19:26:59.000000Z 字数 2353 阅读 1173

HDU 2577 How to Type---(贪心或DP)


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

贪心 动态规划(DP)


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

题意:

Pirates敲键盘,只有大写字母和小写字母组成的字符串,大小写转换时只可以使用caps键和shift键;问你输入该字符串时,最少要按多少次键盘;

解题思路:

我是用的贪心写,但是学长讲的时候是用的DP;
但是自己写贪心的时候少了一种情况:当有如AAiA这种情况,i就可以通过按shift键来打出i;而不是将caps熄灭再按;

完整代码:

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<algorithm>
  4. using namespace std;
  5. char s[110];
  6. int main()
  7. {
  8. int n;
  9. scanf("%d",&n);
  10. while(n--)
  11. {
  12. scanf("%s",s);
  13. int l=strlen(s);
  14. int sum=l;
  15. // printf("%d\n",sum);
  16. int flag=0;
  17. for(int i=0;i<l;i++)
  18. {
  19. if(s[i]>='A'&&s[i]<='Z'&&flag==0)
  20. {
  21. if((s[i+1]>='a'&&s[i+1]<='z')||(i==l-1))
  22. sum++;///shift
  23. else
  24. {
  25. sum++;///caps亮
  26. flag=1;
  27. }
  28. }
  29. else if(((s[i]>='a'&&s[i]<='z')||i==l-1)&&flag==1)
  30. {
  31. if((i!=l-1)&&s[i+1]>='A'&&s[i+1]<='Z')
  32. sum++;
  33. else
  34. {
  35. sum++;
  36. flag=0;
  37. }
  38. }
  39. }
  40. printf("%d\n",sum);
  41. }
  42. return 0;
  43. }
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int dp[110][2];///dp[i][0]表示在第i个字母时caps键没亮,dp[i][1]表示在第i个字母时caps键亮;
  4. char s[110];
  5. int main()
  6. {
  7. int t;
  8. scanf("%d",&t);
  9. while(t--)
  10. {
  11. memset(dp,0,sizeof(dp));
  12. scanf("%s",s);
  13. int l=strlen(s);
  14. if(s[0]>='A'&&s[0]<='Z')
  15. {
  16. dp[0][0]=2;
  17. dp[0][1]=2;
  18. }
  19. else if(s[0]>='a'&&s[0]<='z')
  20. {
  21. dp[0][0]=1;
  22. dp[0][1]=2;
  23. }
  24. for(int i=1;i<l;i++)
  25. {
  26. if(s[i]>='A'&&s[i]<='Z')
  27. {
  28. dp[i][0]=min(dp[i-1][0]+2/*前面caps键没亮,按shift+该字母或caps+该字母*/,dp[i-1][1]+2/*当前灯亮了,先按了该字母,再将caps键灭掉*/);
  29. dp[i][1]=min(dp[i-1][0]+2/*前面caps键没亮,按caps键后再按该字母*/,dp[i-1][1]+1/*当前灯亮了,按了该字母,不用按caps键*/);
  30. }
  31. else if(s[i]>='a'&&s[i]<='z')
  32. {
  33. dp[i][0]=min(dp[i-1][0]+1,dp[i-1][1]+2);
  34. dp[i][1]=min(dp[i-1][0]+2,dp[i-1][1]+2);
  35. }
  36. }
  37. printf("%d\n",dp[l-1][0]);
  38. }
  39. return 0;
  40. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注