DP问题(1) : hdu 2577

题目转自hdu 2577,题目传送门php

题目大意:c++

现给你n个区分大小写的字符串,大小写可用Caps Lock和shift切换(学过计算机的都知道)测试

可是有一点须要注意(shift是切换,若如今是大写锁定,用shift可切换成小写)spa

这道题一开始拿的时候,就以为是n2的dpcode

可是,转移方程一直没想出来(耗时0.25h)blog

后来又仔细想一想,发现是2n的dp字符串

而后想了想,20min就切了get

解题思路:it

咱们先将字符串作预处理,造成一个01字符串io

像这个测试数据:

HELlowORLd

能够转换成这样:

1110001110

而后,就能够写转移方程了

若是目前的字符须要大写,就是这样:

dp[i][0]=min(dp[i-1][0]+1,dp[i-1][1]+1)+1;
dp[i][1]=min(dp[i-1][0]+1,dp[i-1][1])+1;

dp[i][0]表明第i个字符,有大写锁定,dp[i][1]表明第i个字符,无大写锁定

若不须要大写,则是这样:

dp[i][0]=min(dp[i-1][1]+1,dp[i-1][0])+1;
dp[i][1]=min(dp[i-1][1]+1,dp[i-1][0]+1)+1;

(意思本身理解,暴怒蒟蒻在线虐人)

而后就很简单了,AC代码以下(码风清奇,请勿怪罪)

#include<bits/stdc++.h>
using namespace std;
char s[110];
int n,t[110],dp[110][2];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        memset(t,0,sizeof(t));
        scanf("%s",&s);
        int l=strlen(s);
        for(int i=0;i<l;i++) if(s[i]>=65 && s[i]<=90) t[i]=1;//预处理 
        dp[0][1]=2;
        if(t[0]==1) dp[0][0]=2;
        else dp[0][0]=1;//初始化 
        for(int i=1;i<l;i++)
        {
            if(t[i]==1)
            {
                dp[i][0]=min(dp[i-1][0]+1,dp[i-1][1]+1)+1;
                dp[i][1]=min(dp[i-1][0]+1,dp[i-1][1])+1;
            }
            else 
            {
                dp[i][0]=min(dp[i-1][1]+1,dp[i-1][0])+1;
                dp[i][1]=min(dp[i-1][1]+1,dp[i-1][0]+1)+1;
            }//转移方程 
        }
        printf("%d\n",min(dp[l-1][0],dp[l-1][1]+1));//还须要比较 
    }
    return ~~(0-0);//装个13 
}

就这样,这道题就能够轻松AC了......

dp之旅,未完待续.......

相关文章
相关标签/搜索