2192: Wells弹键盘

Description

Wells十分羡慕和佩服那些会弹钢琴的人比如子浩君,然而Wells只会弹键盘…… Wells的键盘只有10个键,从1,2,3,……,9,0,如下图所示:

COJ 2192: Wells弹键盘     (dp)-LMLPHP

而且作为一个正常人,Wells也有两只手,但是为了显示出自己高超的弹键盘水平,Wells决定每只手只动用一个手指,左手指和右手指,来进行按键操作,初始左右手指分别在5,6两个按键上。每一个单位时间(1s),对于一个手指,Wells可以进行如下操作之一:

  • 按下位于手指位置的按键。
  • 将手指向左或向右移动一格,当然不能移到键盘外面。

必须注意以下几点:

  • 在任意时刻,正常人左手指都必须在右手指的左边,当然右手指就在左手指的右边。
  • 在一个单位时间内,只有一个手指可以按下按键。当然,另一个手指还是可以移动的。

现在,给Wells得到一个高级键盘谱(一个仅含0~9的非空字符串)可以在梦里弹出不输于钢琴的旋律,但强迫症Wells一定要知道高级键盘谱弹奏最少要几秒才能弹完,但Wells数学太差了,所以Wells求助于你,本世纪最优秀的程序yuan之一来帮助他!

Input

输入文件有若干行,每行描述一组数据。 对于每组数据仅一行,一个数字串s。

Output

输出若干行,每行为对应输入数据的答案。

Sample Input

434
56
57

Sample Output

5
2
2

Hint

对于20%的数据,0<=length(s)<=5,且数据组数不超过3组; 对于100%的数据,0<=length(s)<=100,且数据组数不超过100组; 保证数据中间没有空行;

Source

解题思路:定义一个三维数组dp[l][r][t]:

其中,l表示左手所在位置,r表示右手所在位置,t表示当前时间,pos表示当前应弹字符的位置,也表示已弹的字符数量。

我们可以从初始状态dp[5][6][0]=0开始遍历时间,每次从当前时间的状态推导下一秒的状态,再取最优。若pos等于给定字符串长度表示已经弹完,结束枚举。对于每个已知状态而言,下一秒共有15个可能的状态能由该状态推导得出。枚举这15个状态即可得出状态转移方程。

 #include <iostream>
#include<cstdio>
#include<set>
#include<queue>
#include<vector>
#include<map>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<string>
#include<cstring> using namespace std;
const int INF=1e9;
int dp[][][];
int main()
{
string s;
int len,ans;
while(cin>>s){
len=s.length();
ans=INF;
memset(dp,-,sizeof(dp));
dp[][][]=;
for(int t=;t<=*len;t++){
for(int l=;l<=;l++){
for(int r=;r<=;r++){
if(r<=l) continue;
if(dp[l][r][t]==len){
ans=t;
break;
}
if(l+''==s[dp[l][r][t]]){
dp[l][r][t+]=max(dp[l][r][t+],dp[l][r][t]+);
if(r+<=)
dp[l][r+][t+]=max(dp[l][r+][t+],dp[l][r][t]+);
if(r->l)
dp[l][r-][t+]=max(dp[l][r-][t+],dp[l][r][t]+);
}
if(r%+''==s[dp[l][r][t]]){
dp[l][r][t+]=max(dp[l][r][t+],dp[l][r][t]+);
if(l->=)
dp[l-][r][t+]=max(dp[l-][r][t+],dp[l][r][t]+);
if(l+<r)
dp[l+][r][t+]=max(dp[l+][r][t+],dp[l][r][t]+);
}
if(l+<r+ && r+<=)
dp[l+][r+][t+]=max(dp[l+][r+][t+],dp[l][r][t]);
if(l+<r)
dp[l+][r][t+]=max(dp[l+][r][t+],dp[l][r][t]);
if(l+<r-)
dp[l+][r-][t+]=max(dp[l+][r-][t+],dp[l][r][t]); if(l<r+ && r+<=)
dp[l][r+][t+]=max(dp[l][r+][t+],dp[l][r][t]);
if(l<r)
dp[l][r][t+]=max(dp[l][r][t+],dp[l][r][t]);
if(l<r-)
dp[l][r-][t+]=max(dp[l][r-][t+],dp[l][r][t]); if(l-<r+ && r+<= && l->=)
dp[l-][r+][t+]=max(dp[l-][r+][t+],dp[l][r][t]);
if(l-<r && l->=)
dp[l-][r][t+]=max(dp[l-][r][t+],dp[l][r][t]);
if(l-<r- && l->=)
dp[l-][r-][t+]=max(dp[l-][r-][t+],dp[l][r][t]);
}
if(ans!=INF)break;
}
if(ans!=INF)break;
}
printf("%d\n",ans);
}
return ;
}
05-18 12:47