dp[i][j][k]:表示第i次踩踏后两脚的位置j,k

先固定一只脚的位置j,第i次踩踏后,状态为dp[i][j][a[i]]或者dp[i][a[i]][j],其中a[i]表示第i个输入的元素,则有状态方程:

x=dp[i-1][k][j]+cost[k][a[i]]; 是通过k踩过来的,cost[k][a[i]]表示k->a[i]的花费。

y=dp[i-1][j][k]+cost[k][a[i]]; 是通过k踩过来的,cost[k][a[i]]表示k->a[i]的花费。

dp[i][j][a[i]]=dp[i][a[i]][j]=min(x,y)

答案:ans=min(dp[n][j][a[i]])

 

#include <iostream>
#include <math.h>
using namespace std;
int a[10005],dp[10005][6][6];
int cost[6][6];
int main(int argc, char *argv[])
{
	int i,j,k,ans,t,n,x,y;
	while(cin>>t&&t)
	{
		a[1]=t;
		for(n=2;;n++)
		{
			cin>>a[n];
			if(!a[n]) break;
		}
		for(i=0;i<5;i++) for(j=0;j<5;j++) cost[i][j]=100000005;
		cost[0][1]=cost[0][2]=cost[0][3]=cost[0][4]=2;
		cost[1][2]=cost[2][1]=cost[2][3]=cost[3][2]=cost[3][4]=cost[4][3]=cost[4][1]=cost[1][4]=3;
		cost[1][3]=cost[3][1]=cost[2][4]=cost[4][2]=4;
		cost[1][1]=cost[2][2]=cost[3][3]=cost[4][4]=1;
		for(i=0;i<=n;i++) for(j=0;j<5;j++) for(k=0;k<5;k++) dp[i][j][k]=100000005;
		dp[0][0][0]=0;ans=100000005;
		for(i=1;i<n;i++)
		{
			for(j=0;j<5;j++)//没动的脚 
			{
				if(j==a[i]) continue;
				x=y=100000005;
				for(k=0;k<5;k++) //左脚踩 
				{
					if(k!=j||k+j==0) if(x>dp[i-1][k][j]+cost[k][a[i]]) x=dp[i-1][k][j]+cost[k][a[i]];
				}
				for(k=0;k<5;k++) //右脚踩 
				{
					if(k!=j||k+j==0) if(y>dp[i-1][j][k]+cost[k][a[i]]) y=dp[i-1][j][k]+cost[k][a[i]]; 
				}
				if(x>y) x=y;
				dp[i][j][a[i]]=dp[i][a[i]][j]=x;
				//cout<<i<<" -> "<<a[i]<<" -> "<<j<<" "<<dp[i][a[i]][j]<<endl;
				if(ans>dp[n-1][j][a[i]]) ans=dp[n-1][j][a[i]];
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}


 


 

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-06-15
  • 2021-04-20
猜你喜欢
  • 2021-10-11
  • 2021-09-23
  • 2021-12-08
  • 2021-07-07
  • 2021-10-14
  • 2021-08-25
  • 2021-11-18
相关资源
相似解决方案