Time Limit: 3000MS | 64bit IO Format: %lld & %llu |
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 }