SERC2013 J You Win!

J:   You Win!
You just  achieved the High  Score on your favorite video game! Now, you get to enter 
your name! You have to use the  controller  to enter  your name, which can be awkward. 
Here’s how it works:
  There  are  only  the  26  capital  letters  A  to  Z,  in  order.  There  are  no  numbers, 
spaces, lower case letters, or any other characters.
  Pushing  UP  or  DOWN  changes  the  active  letter  one  letter  forward  (UP)  or 
backward  (DOWN).  The active  letter  starts at  A.  It will not reset  when you move 
around in the name. It also wraps: UP from Z goes to A, DOWN from A goes to Z.
  Pushing  LEFT  or  RIGHT  moves  the  cursor  one  letter  left  or  right  in  the  current 
name. Note that once the cursor is at either end of the current name, it cannot 
move any further in that direction.
  Pushing the FIRE button adds the active letter to the name. 
For example, consider the name ‘ALMA’. One way you could enter ‘ALMA’ is like this:
Action  # of Pushes  Name (| = Cursor)  Active Letter
FIRE  1  A|  A
UP  11  A|  L
FIRE  1  AL|  L
UP  1  AL|  M
FIRE  1  ALM|  M
DOWN  12  ALM|  A
FIRE  1  ALMA|  A
This would take 28 button pushes. However, consider entering ‘ALMA’ like this:
Action  # of Pushes  Name (| = Cursor)  Active Letter
FIRE  1  A|  A
FIRE  1  AA|  A
LEFT  1  A|A  A
UP  11  A|A  L
FIRE  1  AL|A  L
UP  1  AL|A  M
FIRE  1  ALM|A  M 
2013 ACM ICPC Southeast USA Regional Programming Contest
Page 16 of 16    2 November, 2013
This takes only 17  button pushes. Given a  name, what is the fewest number of  button 
pushes needed to enter that name? Assume that the active  letter  starts at A, and that it 
doesn’t matter where the cursor ends up when you’re done.
Input
There will be  several  test cases in the input. Each test  case will  consist of a single string 
on  its  own  line,  with  from  1  to  18  capital  letters,  representing  a  name  that  must  be 
entered into the High Score list. The input will end with a line with a single 0.
Output
For each test case, output a single integer representing the smallest number of  button 
pushes needed to enter the name. Output no spaces, and do not separate answers with 
blank lines.
Sample Input
ALMA
YES
0
Sample Output

17

21


状态压缩 dp, 这里是用记忆化搜索写的

 开始做的时候多枚举了很多状态导致超时



#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>

using namespace std;

#define inf  1<<30

int f[1<<19][19];
char s[111];
int n,ans;

int dis( char a, char b)
{
    int t= abs( a- b );
    t= min( 26-t , t);
    return t;
}

int  dfs(int x, int  pos)
{
    if (f[x][pos]!=-1 )
        return  f[x][pos];
    int t=inf,y,step;
    y =  ( x ^ (1<<pos) );
    step=0;
    for (int j=pos-1; j>=0; j--)
        if ( y & (1<<j) )
        {
            t= min( t,  dfs( y, j) + step + dis( s[j], s[pos])+1  );
            step++;
        }
    step=1;
    for (int j=pos+1; j<n; j++)
        if ( y & (1<<j) )
        {
            t= min( t,  dfs( y, j) + step + dis( s[j], s[pos])+1  );
            step++;
        }
    f[x][pos]=t;
    return t;
}

int main()
{
    while (scanf("%s",s)!=EOF)
    {
        if (s[0]=='0')
            break;
        n=strlen(s);
        memset(f,-1,sizeof(f));
        for (int i=0; i<n; i++)
            f[1<<i][i]=dis( s[i],'A' ) +1;
        ans=inf;
        for (int i=0; i<n; i++)
           ans= min(ans, dfs( (1<<n) -1  , i)  );
        printf("%d\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值