hdu 2577 dp
来源:互联网 发布:sql if两个判断 编辑:程序博客网 时间:2024/06/05 20:09
题目
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2577
题目来源:群赛(462377900)题目
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=90337#overview 简要题意:要在电脑上输入一串字母
S ,最后大写要关闭,求最少输入的按键数。数据范围:
T≤100;|S|≤100 只含大小写
题解
首先想到的是直接模拟,应该很多人都会有这样的第一感觉。
对每个最长大写子串
S′ 对加上min(2+|S′|,2|S′|) ,对于小写字母直接加。但是这个WA了一发之后就很容易发现不对了,其实可以在大写开启的时候按Shift的。
接下来就很容易想到可以用dp来解决这个问题了。
考虑每位的状态可能是大写或小写,
dp[i][j] 即为打完前i 个字符状态为j 的最少按键数。
不妨让0 表示小写,1 表示大写。再考虑状态之间的转移,分情况稍微讨论一下就行了。
当前位置的字符为小写时,转移方程如下:
当前位置的字符为大写时,转移方程如下,相似地推,就不赘述了: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,小写到大写先按再切换
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)
通过观察不难发现这个公式很好化简,设当前位置的大小写状态为c ,则有:
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) 最终的答案为
dp[|S|][0]
实现
这个真心没啥好说的,直接推就行了,唯一值得一说的点就是 islower(char ch)
这一类函数的返回值其实是int
,我这种喜欢直接赋值过去的就比较容易被坑了,总结下来还是需要多了解系统的函数。复杂度Θ(|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 secondusing 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;}// headconst 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 secondusing 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;}// headconst 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;}
0 0
- hdu 2577 dp
- hdu 2577 DP
- hdu 2577 DP
- HDU 2577 DP || 贪心
- hdu 2577 dp
- DP HDU 2577
- hdu 2577 简单dp
- hdu 2577 dp
- HDU 2577 DP
- hdu 2577(DP)
- hdu 2577 简单dp
- hdu 2577 dp
- HDU DP
- DP? HDU
- DP? HDU
- DP? HDU
- 【dp】HDU
- 【dp】HDU
- 多个表格头合并编辑获取表格内元素内容
- 哗啦啦族的24点游戏(DFS)
- 命运永远都掌握在我们自己的手中
- JavaScript四种跨域方式详解
- 黑马程序员java之网络通讯
- hdu 2577 dp
- 第10章 信号
- 野人学Android基础篇之四大组件第一课--Activity的Intent传递
- 条款17 以独立语句将new对象置入智能指针
- 《剑指Offer》面试题:合并两个排序的链表
- quick-cocos2d-x数据存储之GameState
- 8583报文解析
- 联考1day1总结
- [C++11/14] 自动类型推导——auto