您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: