• CSUOJ 2192: Wells弹键盘 (dp)


    2192: Wells弹键盘

    Description

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

    而且作为一个正常人,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个状态即可得出状态转移方程。

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<set>
     4 #include<queue>
     5 #include<vector>
     6 #include<map>
     7 #include<cmath>
     8 #include<cstdlib>
     9 #include<algorithm>
    10 #include<string>
    11 #include<cstring>
    12 
    13 using namespace std;
    14 const int INF=1e9;
    15 int dp[11][11][1050];
    16 int main()
    17 {
    18     string s;
    19     int len,ans;
    20     while(cin>>s){
    21         len=s.length();
    22         ans=INF;
    23         memset(dp,-1,sizeof(dp));
    24         dp[5][6][0]=0;
    25         for(int t=0;t<=10*len;t++){
    26             for(int l=1;l<=10;l++){
    27                 for(int r=1;r<=10;r++){
    28                     if(r<=l)    continue;
    29                     if(dp[l][r][t]==len){
    30                         ans=t;
    31                         break;
    32                     }
    33                     if(l+'0'==s[dp[l][r][t]]){
    34                         dp[l][r][t+1]=max(dp[l][r][t+1],dp[l][r][t]+1);
    35                         if(r+1<=10)
    36                             dp[l][r+1][t+1]=max(dp[l][r+1][t+1],dp[l][r][t]+1);
    37                         if(r-1>l)
    38                             dp[l][r-1][t+1]=max(dp[l][r-1][t+1],dp[l][r][t]+1);
    39                     }
    40                     if(r%10+'0'==s[dp[l][r][t]]){
    41                         dp[l][r][t+1]=max(dp[l][r][t+1],dp[l][r][t]+1);
    42                         if(l-1>=1)
    43                             dp[l-1][r][t+1]=max(dp[l-1][r][t+1],dp[l][r][t]+1);
    44                         if(l+1<r)
    45                             dp[l+1][r][t+1]=max(dp[l+1][r][t+1],dp[l][r][t]+1);
    46                     }
    47                     if(l+1<r+1 && r+1<=10)
    48                         dp[l+1][r+1][t+1]=max(dp[l+1][r+1][t+1],dp[l][r][t]);
    49                     if(l+1<r)
    50                         dp[l+1][r][t+1]=max(dp[l+1][r][t+1],dp[l][r][t]);
    51                     if(l+1<r-1)
    52                         dp[l+1][r-1][t+1]=max(dp[l+1][r-1][t+1],dp[l][r][t]);
    53                         
    54                         
    55                     if(l<r+1 && r+1<=10)
    56                         dp[l][r+1][t+1]=max(dp[l][r+1][t+1],dp[l][r][t]);
    57                     if(l<r)
    58                         dp[l][r][t+1]=max(dp[l][r][t+1],dp[l][r][t]);
    59                     if(l<r-1)
    60                         dp[l][r-1][t+1]=max(dp[l][r-1][t+1],dp[l][r][t]);
    61                         
    62                     if(l-1<r+1 && r+1<=10 && l-1>=1)
    63                         dp[l-1][r+1][t+1]=max(dp[l-1][r+1][t+1],dp[l][r][t]);
    64                     if(l-1<r && l-1>=1)
    65                         dp[l-1][r][t+1]=max(dp[l-1][r][t+1],dp[l][r][t]);
    66                     if(l-1<r-1 && l-1>=1)
    67                         dp[l-1][r-1][t+1]=max(dp[l-1][r-1][t+1],dp[l][r][t]);
    68                 }
    69                 if(ans!=INF)break;
    70             }
    71             if(ans!=INF)break;
    72         }
    73         printf("%d\n",ans);
    74     }
    75     return 0;
    76 }
    View Code
  • 相关阅读:
    VVDocumenter升级后不能使用问题
    IOS APP结构思路
    statusbar 样式
    在framework中打包xib
    百度地图类参考整理
    UIView的layoutSubviews和drawRect方法何时调用
    写给喜欢用Block的朋友(ios Block)
    启动动画
    navigationcontroller剖析
    消息模式Toast.makeText的几种常见用法
  • 原文地址:https://www.cnblogs.com/zengzk/p/10076817.html
Copyright © 2020-2023  润新知