uva 10618 Tango Tango Insurrection 解题报告

 

Time Limit: 3000MS  64bit IO Format: %lld & %llu

 Status uDebug

  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.
Sample Input
LRLRLLLLRLRLRRRRLLRRLRLDU...D...UUUUDDDD
#
Sample Output
LRLRLLLLRLRLRRRRLLRRLRLRL...R...LLLLRRRR

——————————————————我是分割线————————————————————

DP题目

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<algorithm>
  6 #include<queue>
  7 #include<cstdlib>
  8 #include<iomanip>
  9 #include<cassert>
 10 #include<climits>
 11 #include<functional>
 12 #include<bitset>
 13 #include<vector>
 14 #include<list>
 15 #define maxn 100001
 16 #define F(i,j,k) for(int i=j;i<=k;i++)
 17 #define M(a,b) memset(a,b,sizeof(a))
 18 #define FF(i,j,k) for(int i=j;i>=k;i--)
 19 #define inf 0x3f3f3f3f
 20 #define maxm 1001
 21 #define mod 998244353
 22 //#define LOCAL
 23 using namespace std;
 24 int read(){
 25     int x=0,f=1;char ch=getchar();
 26     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 27     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 28     return x*f;
 29 }
 30 const int LEFT=1;
 31 const int RIGHT=2;
 32 const int MAXN=108;
 33 int n;
 34 int d[MAXN][4][4][3];
 35 char seq[MAXN];
 36 int action[MAXN][4][4][3];
 37 char place[]=".LR";
 38 int pos[256];
 39 int energ(int a,int ta)
 40 {
 41     if (a==ta)    return 3;
 42     if (a+ta==3) return 7;
 43     return 5;
 44 }
 45 int energy(int a,int b,int s,int f,int t,int &ta,int &tb)
 46 {
 47     ta=a;
 48     tb=b;
 49     if (f==1) ta=t;
 50     else if(f==2) tb=t;
 51     if (ta==tb)    return -1; // 下一个状态猜到同一个位置
 52     if (ta==RIGHT&&tb==LEFT) return -1; // 背向跳舞机
 53     if(a==RIGHT&&tb!=b)    return -1; // a左脚在右脚的位置,但是移动了右脚,无论移动到哪儿,都是不合法的
 54     if(b==LEFT&&ta!=a)    return -1;
 55     int e=0;
 56     if(f==0) e=0;
 57     else if(f!=s) e=1;
 58     else 
 59     {
 60         if (f==1) e=energ(a,ta);
 61         else e=energ(b,tb);
 62     }
 63     return e;
 64 }
 65 void update(int i,int a,int b,int s,int f,int t)
 66 {
 67     int ta,tb;
 68     int e;
 69     e=energy(a,b,s,f,t,ta,tb);
 70     if (e<0) return;
 71     int cost=d[i+1][ta][tb][f]+e;
 72     int &ans=d[i][a][b][s];
 73     if (ans>cost)
 74     {
 75         ans=cost;
 76         action[i][a][b][s]=f*4+t; 
 77     }
 78 }
 79 void solve()
 80 {
 81     n=strlen(seq);
 82     memset(d,0,sizeof(d));
 83     for(int i=n-1;i>=0;i--)
 84      for(int a=0;a<4;a++)
 85       for(int b=0;b<4;b++){
 86             if(a==b) continue;
 87             for(int s=0;s<3;s++)
 88             {
 89                 d[i][a][b][s]=0x1f1f1f1f;
 90                 if (seq[i]=='.')
 91                 {
 92                     update(i,a,b,s,0,0);
 93                     for(int t=0;t<4;t++)
 94                     {
 95                         update(i,a,b,s,1,t);
 96                         update(i,a,b,s,2,t);
 97                     }
 98                 }
 99                 else 
100                 {
101                     update(i,a,b,s,1,pos[seq[i]]);
102                     update(i,a,b,s,2,pos[seq[i]]);
103                 }
104             }
105       }
106     int a=1;
107     int b=2;
108     int s=0;
109     for (int i=0;i<n;i++)
110     {
111         int f=action[i][a][b][s]/4;
112         int t=action[i][a][b][s]%4;
113         cout<<place[f];
114         s=f;
115         if(f==1) a=t;
116         else if(f==2) b=t;
117     }
118     cout<<endl;
119     //cout<<d[0][1][2][0]<<endl;
120 }
121 int main()
122 {
123     std::ios::sync_with_stdio(false);//cout<<setiosflags(ios::fixed)<<setprecision(1)<<y;
124     #ifdef LOCAL
125     freopen("data.in","r",stdin);
126     freopen("data.out","w",stdout);
127     #endif
128     pos['U']=0;
129     pos['D']=3;
130     pos['L']=1;
131     pos['R']=2;
132     while(cin>>seq)
133     {
134         if (seq[0]=='#')
135             break;
136         solve();
137     }
138     return 0;
139 }
View Code

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值