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之旅,未完待續.......

相關文章
相關標籤/搜索