poj1726 Tango Tango Insurrection

来源:互联网 发布:fzltchjw gb1 0 mac 编辑:程序博客网 时间:2024/05/02 00:24

You are attempting to learn to play a simple arcade dancing game. The
game has 4 arrows set into a pad: Up, Left, Down, Right. While a song
plays, you watch arrows rise on a screen, and when they hit the top,
you have to hit the corresponding arrows on the pad. There is no
penalty for stepping on an arrow without need, but note that merely
standing on an arrow does not activate it; you must actually tap it
with your foot. Many sequences in the game are very fast-paced, and
require proper footwork if you don’t want to tire yourself out. Write
a program to determine the easiest way to execute a certain sequence
of arrows.

We will work with a basic time unit of an eighth-note. At any given
time, your left foot and right foot will each be on distinct arrows.
Only one foot may perform an action (changing arrows and/or tapping)
during any time unit; jumping is not allowed. Also, you must remain
facing forward in order to see the screen. This puts limitations on
which feet you can use to hit which arrows. Finally, hitting two
arrows in a row with the same foot (“double-tapping”) is exhausting,
because you can’t shift your weight onto that foot. Ideally, you want
to alternate feet all the way through a string of consecutive arrows.

Performing an action with a foot costs 1 unit of energy if it did NOT
perform an action in the previous time unit. If it did, then it costs
3 units if it doesn’t change arrows, 5 units if it moves to an
adjacent arrow, and 7 units if it moves directly across the pad
(between Up and Down, or Left and Right).

Under normal circumstances, you can’t put your left foot on Right, or
your right foot on Left. However, you CAN do a temporary “crossover”:
if your left foot is on Up or Down, you can twist your hips and put
your right foot on Left - but until your right foot moves away, you
can’t move your left to a different arrow. (Imagine the tangle your
legs would get into if you tried!) Similarly, you can cross your left
foot over/behind your right.

Input You will be given multiple arrow sequences to provide foot
guides for. Every sequence consists of a line containing from 1 to 70
characters, representing the arrow that must be hit at each time unit.
The possible characters are U, L, D, and R, signifying the four
arrows, or a period, indicating that no arrow need be hit. Assume that
your left and right feet start on the Left and Right arrows for the
first time unit of a sequence. There are at most 100 sequences. Input
is terminated by a line consisting of a single #.

Output For each input sequence, output a string of the same length,
indicating which foot should perform an action at each time step, or
‘.’ if neither does. If there are multiple solutions that require
minimal energy, any will do.
这里写图片描述
这里写图片描述

用dp[i][x][y][z]表示已经踩了i个箭头,目前左脚在x上,右脚在y上,刚才这一步步【第i步】移动的是z脚,还需要多少能量才能完成。
根据是否有箭头和箭头的方向,枚举下一步的移动并计算费用。

#include<cstdio>#include<cstring>int dp[75][10][10][5],next_f[75][10][10][5],next_d[75][10][10][5],n,a[75];char s[75];int cost(int x,int y){    if (x==y) return 3;    if (x+y==3||x+y==7) return 7;    return 5;}void upd(int sta,int L,int R,int pre,int val,int mv_f,int next_p){    if (val<dp[sta][L][R][pre])    {        dp[sta][L][R][pre]=val;        next_f[sta][L][R][pre]=mv_f;        next_d[sta][L][R][pre]=next_p;    }}void prt(int p,int L,int R,int pre){    if (p==n) return;    switch (next_f[p][L][R][pre])    {        case 0:printf(".");prt(p+1,L,R,0);break;        case 1:printf("L");prt(p+1,next_d[p][L][R][pre],R,1);break;        case 2:printf("R");prt(p+1,L,next_d[p][L][R][pre],2);break;    }}int main(){    int i,j,k,p,q,x,y,z,u,v,w;    while (scanf("%s",s+1)&&s[1]!='#')    {        n=strlen(s+1);        for (i=1;i<=n;i++)          switch (s[i])           {            case '.':a[i]=0;break;            case 'L':a[i]=1;break;            case 'R':a[i]=2;break;            case 'U':a[i]=3;break;            case 'D':a[i]=4;break;          }        memset(dp,0x3f,sizeof(dp));        for (x=1;x<=4;x++)          for (y=1;y<=4;y++)            for (z=0;z<=2;z++)              dp[n][x][y][z]=0;        for (i=n-1;i>=0;i--)          for (x=1;x<=4;x++)            for (y=1;y<=4;y++)              if (x!=y)                for (z=0;z<=2;z++)                  if (a[i+1]==0)                  {                      upd(i,x,y,z,dp[i+1][x][y][0],0,0);                      for (w=1;w<=4;w++)                      {                        if (w!=y&&(y!=1||w==x))                          upd(i,x,y,z,dp[i+1][w][y][1]+ (z==1?cost(w,x):1),1,w);                        if (w!=x&&(x!=2||w==y))                          upd(i,x,y,z,dp[i+1][x][w][2]+ (z==2?cost(w,y):1),2,w);                      }                  }                  else                  {                    w=a[i+1];                    if (w!=y&&(y!=1||w==x))                      upd(i,x,y,z,dp[i+1][w][y][1]+ (z==1?cost(w,x):1),1,w);                    if (w!=x&&(x!=2||w==y))                      upd(i,x,y,z,dp[i+1][x][w][2]+ (z==2?cost(w,y):1),2,w);                  }        prt(0,1,2,0);        printf("\n");    }}
0 0
原创粉丝点击