1. 程式人生 > >HDU2577 How to Type【DP】

HDU2577 How to Type【DP】

print data 輸出 指示燈 char tchar set 狀態 初始

題目鏈接: http://acm.hdu.edu.cn/showproblem.php?

pid=2577


題目大意: 給你一個僅僅包括大寫和小寫字母的字符串,如今Pirates從鍵盤上輸出它。按CapsLk可

啟關閉大寫和小寫指示燈。

按Shift可轉換將輸入字母的大寫和小寫而不改變CapsLk的開關狀態。Pirates有

一個壞習慣,假設輸入的時候CapsLk是開著的,那麽輸入結束後必須把它關閉。

問,輸入一個字符

串,最小的按鍵數目是多少


思路:

用兩個數組dpa和dpb分別來表示CapsLk關閉狀態和開啟狀態的最小操作數。

假設將要輸入的字母是小寫字母:

dpa[i+1] = min(dpa[i]+1,dpb[i]+2); 不開燈的情況下直接按字母,開燈情況則先關燈再按字母
dpb[i+1] = min(dpa[i]+2,dpb[i]+2); 不開燈的情況下按字母再開燈。開燈情況下Shift+按字母,

最後保持開燈狀態

假設將要輸入的字母是大寫字母:

dpa[i+1] = min(dpa[i]+2,dpb[i]+2); 不開燈的情況下按Shift+字母,開燈情況下則按字母再關燈
dpb[i+1] = min(dpa[i]+2,dpb[i]+1); 不開燈的情況下開燈按字母。開燈情況下直接按字母

最後dpb[len]++,要把燈關掉。

初始化為dpa[0] = 0。dpb[0] = 1,由於dpb狀態剛開始要開燈。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

int dpa[110],dpb[110];
char a[110];

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        getchar();
        scanf("%s",a);
        memset(dpa,0,sizeof(dpa));
        memset(dpb,0,sizeof(dpb));
        dpa[0] = 0;//dpa為關燈狀態最小操作數
        dpb[0] = 1;//dpb為開燈狀態最小操作數
        int len = strlen(a);
        for(int i = 0; i < len; i++)
        {
            if(a[i]>=‘a‘ && a[i]<=‘z‘)
            {
                dpa[i+1] = min(dpa[i]+1,dpb[i]+2);
                dpb[i+1] = min(dpa[i]+2,dpb[i]+2);
            }
            else
            {
                dpa[i+1] = min(dpa[i]+2,dpb[i]+2);
                dpb[i+1] = min(dpa[i]+2,dpb[i]+1);
            }
        }
        dpb[len]++;
        int ans = min(dpa[len],dpb[len]);
        printf("%d\n",ans);
    }
    return 0;
}


HDU2577 How to Type【DP】