很棒的题目,锻炼了心理素质。
#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
int dp[10005][5][5];
bool flag[10005][5][5];
int ko[10005];
int mini(int a,int b)
{
if(a<b)
return a;
return b;
}
int count(int x,int y)
{
if(x==0&&y!=0)
return 2;
else if(x==y)
return 1;
else if(x==1&&y==3)
return 4;
else if(x==3&&y==1)
return 4;
else if((x==2&&y==4)||(x==4&&y==2))
return 4;
else if(x!=0&&y!=0)
return 3;
}
int main()
{
int i,j,k,length,ans;
while(scanf("%d",&ko[1]))
{
if(ko[1]==0)
break;
length=2;
while(scanf("%d",&ko[length]))
{
if(ko[length]==0)
break;
length=length+1;
}
length=length-1;
for(i=0;i<=length;i++)
for(j=0;j<=4;j++)
for(k=0;k<=4;k++)
flag[i][j][k]=false;
dp[0][0][0]=0;
flag[0][0][0]=true;
dp[1][ko[1]][0]=2;
flag[1][ko[1]][0]=true;
dp[1][0][ko[1]]=2;
flag[1][0][ko[1]]=true;
for(i=2;i<=length;i++)
{
for(k=0;k<=4;k++)
{
if(k==ko[i])
continue;
ans=1000000;
for(j=0;j<=4;j++)
if(flag[i-1][j][k]==true&&j!=k)
ans=mini(ans,dp[i-1][j][k]+count(j,ko[i]));
if(ans<1000000)
{
flag[i][ko[i]][k]=true;
dp[i][ko[i]][k]=ans;
}
}
for(k=0;k<=4;k++)
{
if(k==ko[i])
continue;
ans=1000000;
for(j=0;j<=4;j++)
if(flag[i-1][k][j]==true&&j!=k)
ans=mini(ans,dp[i-1][k][j]+count(j,ko[i]));
if(ans<1000000)
{
flag[i][k][ko[i]]=true;
dp[i][k][ko[i]]=ans;
}
}
}
ans=10000000;
for(i=0;i<=4;i++)
{
if(flag[length][i][ko[length]]==true)
ans=mini(ans,dp[length][i][ko[length]]);
if(flag[length][ko[length]][i]==true)
ans=mini(ans,dp[length][ko[length]][i]);
}
cout<<ans<<endl;
}
return 0;
}