还记得当年看黑书的时候就看到过这个题,当时看书看了好久都没看懂,今天又看到这题,感觉不是很难了,啊哈哈。
题意是大胖子跳跳舞机,从某一地方移动到另一个地方需要消耗不同的体力,给出跳舞机需要踩的顺序,求最小需要的体力。跳舞机可以踩的一共就5个位置,所以可以以双腿的位置为状态,在这题中左右腿是没有区别的,所以只需要记录不同的就好了,然后根据两个腿的位置算出分别要移动到给定的位置需要的体力就行了。因为这题没给数据大小,我就用了个滚动数组搞了……
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
int dp[30][2];
int getpoints(int x,int y)
{
if(x==0) return 2;
if(x==y) return 1;
if(abs(x-y)==2) return 4;
return 3;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int k;
while(~scanf("%d",&k))
{
if(k==0) break;
for(int i=0;i<25;++i) dp[i][0]=inf;
dp[k][0]=2;
int t=1,x,y,tmp;
while(scanf("%d",&k))
{
if(k==0) break;
for(int i=0;i<25;++i) dp[i][t]=inf;
for(int i=0;i<5;++i)
for(int j=i+1;j<5;++j)
{
if(dp[i*5+j][t^1]==inf) continue;
if(k==i||k==j) dp[i*5+j][t]=min(dp[i*5+j][t],dp[i*5+j][t^1]+1);
//i->k
tmp=getpoints(i,k);
x=k;y=j;
if(x>y) swap(x,y);
dp[x*5+y][t]=min(dp[x*5+y][t],dp[i*5+j][t^1]+tmp);
//j->k
tmp=getpoints(j,k);
x=i;y=k;
if(x>y) swap(x,y);
dp[x*5+y][t]=min(dp[x*5+y][t],dp[i*5+j][t^1]+tmp);
}
t^=1;
}
int ans=inf;
for(int i=0;i<25;++i) ans=min(ans,dp[i][t^1]);
printf("%d\n",ans);
}
return 0;
}