现在的位置: 首页 > 综合 > 正文

UVA – 1291(简单dp,跳舞机,两条腿可同时移动)

2019年04月03日 ⁄ 综合 ⁄ 共 1191字 ⁄ 字号 评论关闭

d[ i ][ j ][ k ] 代表当前i个箭头已经跳过,左腿在j右腿在k时候的最小移动代价;

注意两条腿可以同时移动;

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<cmath>
#include<cstring>
#include <iostream>
using namespace std;
const int maxn = 110;
const int inf  = 1000000;
int c[5][5];
void init(){
  for(int i=1;i<=4;i++)
    c[i][0]=c[0][i]=2;
  for(int i=1;i<=4;i++){
     int te = i==4? 1:i+1;
     c[te][i]=c[i][te]=3;
     c[i][i] = 1;
  }
  c[0][0] = 1;
  c[1][3]=c[3][1]=4;
  c[2][4]=c[4][2]=4;
}
int d[10005][5][5],n,a[10010];
bool vis[10005][5][5];
/*top is 1, the left is 2, the bottom is 3, and the right is 4*/
int dp(int i,int j,int k){
  if(vis[i][j][k]) return d[i][j][k];
  vis[i][j][k] = true;
  int& ans = d[i][j][k];
  if(i==n){
      return d[i][j][k] = 0;
   }
  ans=inf;
  if(j==a[i+1]||k==a[i+1]){
     if(j==a[i+1]){
        for(int x=0;x<=4;x++){
             int add1 = k==x ? 0 : c[k][x];
             ans=min(ans,dp(i+1,j,x)+1+add1);
        }
     }
     else {
        for(int x=0;x<=4;x++){
             int add2 = j==x ? 0 : c[j][x];
             ans=min(ans,dp(i+1,x,k)+1+add2);
        }
     }
  }
  else {
     for(int x=0;x<=4;x++){
       int add1 = k==x ? 0 : c[k][x];
       int add2 = j==x ? 0 : c[j][x];
       ans=min(ans,dp(i+1,a[i+1],x)+c[j][a[i+1]]+add1);
       ans=min(ans,dp(i+1,x,a[i+1])+c[k][a[i+1]]+add2);
     }
  }
  return ans;
}
int main()
{
    init();
    int x;
    while(scanf("%d",&x)==1 && x){
       n=0;
       a[++n]=x;
       while(scanf("%d",&x)&&x){
          a[++n] = x;
       }
       memset(vis,false,sizeof(vis));
       printf("%d\n",dp(0,0,0));
    }
    return 0;
}

抱歉!评论已关闭.