hdu2577一道很不错的DP

来源:互联网 发布:无线连接投影仪软件 编辑:程序博客网 时间:2024/05/17 07:25

题目描述

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 0x3f3f3f3fchar 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;}
0 0
原创粉丝点击