“炫舞家“ST
时间限制:3000 ms | 内存限制:65535 KB
难度:4
-
描述
-
ST是一个酷爱炫舞的玩家。TA很喜欢玩QQ炫舞,因此TA也爱屋及乌的喜欢玩跳舞机(Dance Dance Revolution,DDR)。但是TA每天还要努力的学习,因此TA希望每次都保存最多的体力来学习。
DDR的主要内容是用脚来踩踏板。踏板有4个方向的箭头,用1,2,3,4来代表,如下图所示。
游戏规则如下:
每首歌曲有一个箭头序列,游戏者必须按照这个序列依次用某一只脚踩相应的踏板。在任何时候,两只脚都不能在同一个踏板上,但可以同时待在中心位置0(一开始游戏的时候,游戏者的双脚都在中心位置0处)。
每一个时刻,TA必须移动而且只能移动TA的一只脚去踩相应的箭头,而另一只脚不许移动。这样,TA跳DDR的方式可以用一串数字L1L2………Ln来表示。
其中体力消耗规则如下:
1、 从中心往任何一个箭头耗费2个单位体力;
2、 从任何一个箭头移动到相邻箭头耗费3个单位体力(1和3相对,2和4相对)耗费4个单位体力。
3、 留在原地在踩一下只需要1单位。
现在炫舞家ST很想学习但是又想玩DDR。因此,TA希望厉害的程序员你可以帮TA编写一个程序计算出TA因该怎样移动他的双脚(即,对于每个箭头,选一只脚去踩它),才能用最少的体力完成给定的舞曲。
例如,给出22140,总的体力耗费为2+1+2+3=8单位。
#include <stdio.h>
#include <string.h>
#define min(a,b)(a<b?1:0)
const int MAX = 10000;
struct Foot
{
int x,y;
}pos[MAX];
int dp[6][6][MAX],f[MAX];
int e[6][6]={
{1,2,2,2,2},
{0,1,3,4,3},
{0,3,1,3,4},
{0,4,3,1,3},
{0,3,4,3,1}
};
int main()
{
int i,j,n;
while(scanf("%d",&f[1]),f[1])
{
memset(dp,0,sizeof(dp));
for(n = 2;f[n-1]!=0;n++)
scanf("%d",&f[n]);
n-=2; f[0] = 0;
pos[0].x = 0; pos[0].y = 0;
for(i = 0;i <= n;i++)
{
int X = dp[f[i]][pos[i].y][i+1]+e[pos[i].x][f[i]];
int Y = dp[pos[i].x][f[i]][i+1]+e[pos[i].y][f[i]];
if(min(X,Y)){
pos[i+1].x = f[i];
pos[i+1].y = pos[i].y;
dp[pos[i].x][pos[i].y][i] = X;
}else
{
pos[i+1].y = f[i];
pos[i+1].x = pos[i].x;
dp[pos[i].x][pos[i].y][i] = Y;
}
}
}
return 0;
}