hdu 2577 dp
2015-09-05 13:46
393 查看
题目
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2577题目来源:群赛(462377900)题目
\qquad \quad \ \ \ \ http://acm.hust.edu.cn/vjudge/contest/view.action?cid=90337#overview
简要题意:要在电脑上输入一串字母SS,最后大写要关闭,求最少输入的按键数。
数据范围:T≤100;|S|≤100T\leq 100;\quad |S|\leq100\quad只含大小写
题解
首先想到的是直接模拟,应该很多人都会有这样的第一感觉。对每个最长大写子串S′S'对加上min(2+|S′|,2|S′|)min(2+|S'|,2|S'|),对于小写字母直接加。
但是这个WA了一发之后就很容易发现不对了,其实可以在大写开启的时候按Shift的。
接下来就很容易想到可以用dp来解决这个问题了。
考虑每位的状态可能是大写或小写,dp[i][j]dp[i][j]即为打完前ii个字符状态为jj的最少按键数。
不妨让00表示小写,11表示大写。
再考虑状态之间的转移,分情况稍微讨论一下就行了。
当前位置的字符为小写时,转移方程如下:
dp[i][0]dp[i][1]=min(dp[i−1][0]+1,dp[i−1][1]+2) 小写到小写按一下,大写到小写切换再按一下=min(dp[i−1][1]+2,dp[i−1][0]+2) 大写到大写要按Shift,小写到大写先按再切换\begin{equation}
\begin{aligned}
dp[i][0]&=min(dp[i-1][0]+1, dp[i-1][1]+2)~~~~~~~小写到小写按一下,大写到小写切换再按一下 \\
dp[i][1]&=min(dp[i-1][1]+2, dp[i-1][0]+2)~~~~~~~大写到大写要按Shift,小写到大写先按再切换
\end{aligned}\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad
\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad
\qquad \qquad \qquad \qquad
\end{equation} 当前位置的字符为大写时,转移方程如下,相似地推,就不赘述了:
dp[i][1]dp[i][0]=min(dp[i−1][1]+1,dp[i−1][0]+2)=min(dp[i−1][0]+2,dp[i−1][1]+2)\begin{equation}
\begin{aligned}
dp[i][1] &= min(dp[i-1][1]+1, dp[i-1][0]+2)\\
dp[i][0] &= min(dp[i-1][0]+2, dp[i-1][1]+2)
\end{aligned}\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad
\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad
\qquad \qquad \qquad \qquad
\end{equation}
\\
通过观察不难发现这个公式很好化简,设当前位置的大小写状态为cc,则有:
dp[i][c]dp[i][1−c]=min(dp[i−1][c]+2,dp[i−1][1−c]+2)=min(dp[i−1][1−c]+1,dp[i−1][c]+2) \begin{equation}
\begin{aligned}
dp[i][c] &= min(dp[i-1][c]+2, dp[i-1][1-c]+2)\\
dp[i][1-c] &= min(dp[i-1][1-c]+1, dp[i-1][c]+2)
\end{aligned}\qquad \qquad \qquad \qquad \qquad \qquad \ \qquad \qquad \qquad \qquad \qquad
\qquad \qquad \qquad \qquad
\end{equation}
最终的答案为dp[|S|][0]dp[|S|][0]
实现
\quad\ \ 这个真心没啥好说的,直接推就行了,唯一值得一说的点就是islower(char ch)这一类函数的返回值其实是
int,我这种喜欢直接赋值过去的就比较容易被坑了,总结下来还是需要多了解系统的函数。复杂度Θ(|S|)\Theta(|S|)。
朴素代码
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> #include <stack> #include <queue> #include <string> #include <vector> #include <set> #include <map> #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define sz(x) ((int)(x).size()) #define fi first #define se second using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;} // head const int INF = 0x3f3f3f3f; char s[105]; int dp[105][2]; int main() { int t; scanf("%d", &t); while (t--) { scanf("%s", s+1); int len = strlen(s+1); bool flag = false; memset(dp, INF, sizeof dp); dp[0][0] = 0; for (int i = 1; i <= len; i++) { if (islower(s[i])) { dp[i][0] = min(dp[i-1][0]+1, dp[i-1][1]+2); dp[i][1] = min(dp[i-1][1]+2, dp[i-1][0]+2); } else { dp[i][1] = min(dp[i-1][1]+1, dp[i-1][0]+2); dp[i][0] = min(dp[i-1][0]+2, dp[i-1][1]+2); } } printf("%d\n", dp[len][0]); } return 0; }
化简代码
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> #include <stack> #include <queue> #include <string> #include <vector> #include <set> #include <map> #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define sz(x) ((int)(x).size()) #define fi first #define se second using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;} // head const int INF = 0x3f3f3f3f; char s[105]; int dp[105][2]; int main() { int t; scanf("%d", &t); while (t--) { scanf("%s", s+1); int len = strlen(s+1); bool flag = false; memset(dp, INF, sizeof dp); dp[0][0] = 0; for (int i = 1; i <= len; i++) { int c = islower(s[i]) ? 1 : 0; dp[i][c] = min(dp[i-1][c], dp[i-1][1-c])+2; dp[i][1-c] = min(dp[i-1][1-c]+1, dp[i-1][c]+2); } printf("%d\n", dp[len][0]); } return 0; }
相关文章推荐
- 第10章 信号
- 野人学Android基础篇之四大组件第一课--Activity的Intent传递
- Linux下JDK环境变量配置
- 黑马程序员java之网络通讯
- JavaScript四种跨域方式详解
- 命运永远都掌握在我们自己的手中
- android学习笔记(15)Android消息机制
- BIT
- 浅谈人生中的失败与成功
- URLConnection用法详情
- 多个表格头合并编辑获取表格内元素内容
- 数据结构 - 排序
- 从零开始学JAVA DAY9
- 做一个像狼一样的男人
- HDU 3501 Calculation 2
- 递归简介
- javascript面向对象设计
- 使用MediaPlayer播放音频文件
- 表格编辑表头多行并列多列并列
- 图像信号的稀疏性