hdu2577 dp

这题算是比较简单吧,dp[i][0]表示non-caps,dp[i][1]表示caps

状态转移方程还是比较简单的,注意小写的时候 caps+shift = lower

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <string>

const int inf = (1<<31);
const int MAXN = 1e5+10;

using namespace std;
int a[MAXN][2];

int main()
{
    int t;
    scanf("%d",&t);
    string s;
    while(t--){
        cin>>s;
        int n = s.length();
        int mmin = inf;
        //cout<<n<<endl;
        a[0][1] = 1;
        a[0][0] = 0;
        for(int i=1;i<=n;i++){
            if(s[i-1]<=‘Z‘&&s[i-1]>=‘A‘){
                a[i][0] = min(a[i-1][0]+2,a[i-1][1]+2);
                a[i][1] = min(a[i-1][0]+2,a[i-1][1]+1);
            }
            else if(s[i-1]<=‘z‘&&s[i-1]>=‘a‘){
                a[i][0] = min(a[i-1][0]+1,a[i-1][1]+2);
                a[i][1] = min(a[i-1][0]+2,a[i-1][1]+2); //caps+shift = lower
            }
        }
        mmin = min(a[n][1]+1,a[n][0]);
        cout<<mmin<<endl;
    }
    return 0;
}

时间: 2024-11-01 01:38:49

hdu2577 dp的相关文章

[HDU2577]How to Type(DP)

题目链接 题意 给一个大小写字符串,求最少敲击字符串次数,最开始和最后要求shift都是down的.如日常,大小写转换可以ctrl+z或者shift保持 up/down. 题解 两个dp数组,一个表示当前shift状态是up的最小转换次数,一个表示当前shift状态是down的最小转换次数.最后做处理和比较,再加上字符数即可. 代码 import java.util.Scanner; public class Main { public static void main(String args[

HDU-2577 How to Type DP

字符输入问题,刚开始没有考虑到shift+字符输入和当前大小写锁定状态相反状态字符只需要两步的问题. 状态转移方程:dp1[i]表示输入完第i个字符后为大写状态需要的步数 dp2[i]表示输入完第i个字符后为小写状态所需要的步数 如果第i个字符为小写: dp1[i]=min(dp1[i-1]+2,dp2[i-1]+2); dp2[i]=min(dp1[i-1]+2,dp2[i-1]+1); 如果第i个字符为大写: dp1[i]=min(dp1[i-1]+1,dp2[i-1]+2): dp2[i]

HDU2577 How to Type【DP】

题目链接: http://acm.hdu.edu.cn/showproblem.php? pid=2577 题目大意: 给你一个仅仅包括大写和小写字母的字符串,如今Pirates要从键盘上输出它.按CapsLk可开 启关闭大写和小写指示灯. 按Shift可转换将输入字母的大写和小写而不改变CapsLk的开关状态.Pirates有 一个坏习惯,假设输入的时候CapsLk是开着的,那么输入结束后必须把它关闭. 问,输入一个字符 串,最小的按键数目是多少 思路: 用两个数组dpa和dpb分别来表示Ca

DP总结 ——QPH

常见优化 单调队列 形式 dp[i]=min{f(k)} dp[i]=max{f(k)} 要求 f(k)是关于k的函数 k的范围和i有关 转移方法 维护一个单调递增(减)的队列,可以在两头弹出元素,一头压入元素. 队列中维护的是两个值.一个是位置,这和k的范围有关系,另外一个是f(k)的值,这个用来维护单调性,当然如果f(k)的值可以利用dp值在O(1)的时间内计算出来的话队列中可以只维护一个表示位置的变量. 枚举到一个i的时候,首先判断队首元素的位置是否已经不满足k的范围了,如果不满足就将队首

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

POJ - 3186 Treats for the Cows (区间DP)

题目链接:http://poj.org/problem?id=3186 题意:给定一组序列,取n次,每次可以取序列最前面的数或最后面的数,第n次出来就乘n,然后求和的最大值. 题解:用dp[i][j]表示i~j区间和的最大值,然后根据这个状态可以从删前和删后转移过来,推出状态转移方程: dp[i][j]=max(dp[i+1][j]+value[i]*k,dp[i][j-1]+value[j]*k) 1 #include <iostream> 2 #include <algorithm&

51Nod 1009 数字1的个数 | 数位DP

题意: 小于等于n的所有数中1的出现次数 分析: 数位DP 预处理dp[i][j]存 从1~以j开头的i位数中有几个1,那么转移方程为: if(j == 1) dp[i][j] = dp[i-1][9]*2+pow(10,i-1);else dp[i][j] = dp[i-1][9]+dp[i][j-1]; 然后注意下对于每个询问统计的时候如果当前位为1需要额外加上他后面所有位数的个数,就是n%pow(10,i-1); 这样总复杂度log(n)*10 #include <bits/stdc++.

HDU 3555 Bomb (数位DP)

数位dp,主要用来解决统计满足某类特殊关系或有某些特点的区间内的数的个数,它是按位来进行计数统计的,可以保存子状态,速度较快.数位dp做多了后,套路基本上都差不多,关键把要保存的状态给抽象出来,保存下来. 简介: 顾名思义,所谓的数位DP就是按照数字的个,十,百,千--位数进行的DP.数位DP的题目有着非常明显的性质: 询问[l,r]的区间内,有多少的数字满足某个性质 做法根据前缀和的思想,求出[0,l-1]和[0,r]中满足性质的数的个数,然后相减即可. 算法核心: 关于数位DP,貌似写法还是