nyoj 740

http://acm.nyist.net/JudgeOnline/problem.php?pid=740

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <memory.h>
#define M 1000010
int a[M],dp[M][5][5],c[5][5];
int main()
{
long x,y,ans;
int t,i,j,k,n;
for(i=0;i<=4;i++)
{
for(j=0;j<=4;j++)
{
if(j==0&&i!=j)
{
c[i][j]=0;
}
else if(i==0)
{
if(i!=j)
{

c[i][j]=2;
c[j][i]=0;
}
else
c[i][j]=1;
}
else if(i==j)
c[i][j]=1;
else if(abs(i-j)==2)
{
c[i][j]=c[j][i]=4;
}
else
c[i][j]=c[j][i]=3;
printf("%d ",c[i][j]);
}
printf("\n");
}

while(scanf("%d",&n)&&n)
{

memset(dp,9999,sizeof(dp)); // 脚没真正踩过的地方 初始化为无穷大 
a[1]=n;
for(n=2;;n++)
{
scanf("%d",&a[n]);
if(!a[n]) break;
}
dp[0][0][0]=0;
ans=1000500;
for(i=1;i<n;i++)
{
for(j=0;j<=4;j++)  // 一只脚固定 
{ // 如果 在i-1状态时 某个脚没有真正在 j 则已经被初始化为无穷大 

y=x=1000500;
if(j==a[i]) continue;// 两只脚不踩在同一个地方 
for(k=0;k<=4;k++)     
{
if(x>dp[i-1][k][j]+c[k][a[i]]) x=dp[i-1][k][j]+c[k][a[i]]; //用左脚 
}
for(k=0;k<=4;k++)
{
if(y>dp[i-1][j][k]+c[k][a[i]]) y=dp[i-1][j][k]+c[k][a[i]]; //用右脚 
}
if(x>y) 
x=y;

dp[i][a[i]][j]=dp[i][j][a[i]]=x; // 把L R 交换最优解不变 
if(ans>dp[n-1][a[i]][j])
ans=dp[n-1][a[i]][j];
}
}
printf("%ld\n",ans);

}
return 0;
}

你可能感兴趣的:(dp,nyoj)