hdu 2577 How to Type (动态规划 入门好题)

题意:给你一个字符,有大写小写,你模拟键盘打字母的操作,可以shirft变换当前字母,可以开CapsLock灯,最后需要关掉。
因为有两个操作,需要两个维度表示状态转移。
定义:二维 dp[i ][2] ,前i个字母对应当前是 0,1操作 的最小操作。
所以有对应的状态转移方程:(见代码)
有一个细节写错了,dp[i][1]=min(…,dp[i-1][1]+2) 而不是3,这里意思是当前大写灯开了,需要打小写字母之后转态大写灯还是开的,我错误想法是关掉大写灯,写小写字母,再打开,三步,正确是,shift +字母,两步、、、、、

#include <fstream>
#include <iostream>
#include <string>
#include <complex>
#include <math.h>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stdio.h>
#include <stack>
#include <algorithm>
#include <list>
#include <ctime>
#include <memory.h>
#include <ctime>
#include <assert.h>

#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define eps 1e-8
#define M_PI 3.141592653589793

typedef long long ll;
const ll mod=1000000007;
const int inf=99999999;
ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}

using namespace std;
int dp[110][2];
string s;
int main()
{
    int n;cin>>n;
    while(n--){
        cin>>s;
    int len=s.size();
    memset(dp,0,sizeof(dp));
    dp[0][1]=1;
    for(int i=0;i<len;i++){
       if(s[i]>='A'&&s[i]<='Z'){
        dp[i+1][0]=min(dp[i][0]+2,dp[i][1]+2);
        dp[i+1][1]=min(dp[i][0]+2,dp[i][1]+1);
       }
       else if(s[i]>='a'&&s[i]<='z'){
        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);//
       }
    }
    dp[len][1]++;
    /* for(int i=0;i<=len;i++){ for(int j=0;j<2;j++){ cout<<dp[i][j]<<" "; } cout<<endl; }*/
    cout<<min(dp[len][0],dp[len][1])<<endl;
    }
}

你可能感兴趣的:(dp,动态规划)