UVa 10618 Tango Tango Insurrection
2016-09-07 14:46
288 查看
本质上就是个简单的动规,但是各种条件限制太鬼畜了……
强行肝了大概四个多小时总算肝过去了,其中有三个小时是没发现输出代码有bug,一直在调已经对了的其他部分……
开四维数组f[决策步数][左脚位置][右脚位置][移动情况(不动|动左脚|动右脚)]=最小能量消耗,再开一个四维数组存储路径。
如果是‘.’那么枚举各种走法取最优方案,如果是按键,枚举左脚或者右脚去踩,取最优方案。
由于前一步的动作会影响到下一步的能量消耗,所以需要倒着动规。原本写了倒序循环的动规,在↑那心力交瘁的三个小时里改成了类DFS的形式……
代码写得很详细了:
//紫书P290 #include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> using namespace std; const int mxn=90; struct node{ int l,r,last; }ap[mxn][6][6][6]; int f[mxn][6][6][6]; //[已决策步数][左脚(上,下,左,右)][右脚(上,下,左,右)][上次移动脚(无,左,右)] // 0 1 2 3 0 1 2 char s[mxn]; int n; bool pd(int l,int r,int nl,int nr){//移动合法性判断 if(nl==l && nr==r)return 1; if(nl==l)//左脚不动 if(nr!=l && l!=3)return 1; if(nr==r)//右脚不动 if(nl!=r && r!=2)return 1; return 0; } int cost(int f,int t,int last,int now){//起点,终点,上次移动脚,本次移动脚 if(last!=now)return 1;//无动作 if(f==t)return 3;//只踩不移动 if(f!=(t^1))return 5;//移动到相邻位置 return 7;//移动到相对位置 } int dp(int i,int l,int r,int last){ int& ans=f[i][l][r][last];//动规答案 node& a=ap[i][l][r][last];//路径 if(ans!=0x3f3f3f3f)return ans; if(i==n)return ans=0;//到达起始状态,递归返回 if(s[i]=='.'){ //不移动 ans=min(ans,dp(i+1,l,r,0)); a.l=l;a.r=r;a.last=0; //四方向移动 for(int j=0;j<4;j++){ //动左脚 if(pd(l,r,j,r)){ int tmp=dp(i+1,j,r,1)+cost(l,j,last,1); if(ans>tmp){ ans=tmp; a.l=j;a.r=r;a.last=1; } } //动右脚 if(pd(l,r,l,j)){ int tmp=dp(i+1,l,j,2)+cost(r,j,last,2); if(ans>tmp){ ans=tmp; a.l=l;a.r=j;a.last=2; } } } return ans; } // else{ int dir=0;//目标移动方向 switch(s[i]){ case 'L':{dir=2;break;} case 'R':{dir=3;break;} case 'U':{dir=0;break;} case 'D':{dir=1;break;} } //动右脚 if(pd(l,r,l,dir)){ int tmp=dp(i+1,l,dir,2)+cost(r,dir,last,2); if(tmp<ans){ ans=tmp; a.l=l;a.r=dir;a.last=2; } } //动左脚 if(pd(l,r,dir,r)){ int tmp=dp(i+1,dir,r,1)+cost(l,dir,last,1); if(tmp<ans){ ans=tmp; a.l=dir;a.r=r;a.last=1; } } return ans; // } } void Print(){//输出方案 int nl=2,nr=3,last=0;//初始状态 for(int i=0;i<=n;i++){ int tpl=nl,tpr=nr,tplast=last; if(i>0){ if(last==0)printf("."); else if(last==1)printf("L"); else printf("R"); } nl=ap[i][tpl][tpr][last].l; nr=ap[i][tpl][tpr][last].r; last=ap[i][tpl][tpr][last].last; } return; } int main(){ int i,j; while(scanf("%s",s) && s[0]!='#'){ memset(f,0x3f,sizeof f); n=strlen(s); dp(0,2,3,0);//从初始状态开始动规 Print(); printf("\n"); } return 0; }
相关文章推荐
- UVA 10618 Tango Tango Insurrection(DP)
- uva 10618 Tango Tango Insurrection 解题报告
- 【暑假】[深入动态规划]UVa 10618 Tango Tango Insurrection
- UVa-10618 Tango Tango Insurrection&& UVa-1627 Team them up!
- Tango Tango Insurrection UVA - 10618
- 【暑假】[深入动态规划]UVa 10618 Tango Tango Insurrection
- UVa10618 Tango Tango Insurrection
- uva 10618 Tango Tango Insurrection 解题报告
- 【Uva 10618】Tango Tango Insurrection
- uva 10618 Tango Tango Insurrection 动态规划
- uva 10618 Tango Tango Insurrection (DP)WA
- UVA 10618 - Tango Tango Insurrection【DP】
- 10618 - Tango Tango Insurrection
- 【暑假】[深入动态规划]UVa 10618 Fun Game
- 紫书例题9-18 Tango Tango Insurrection
- 【暑假】[深入动态规划]UVa 10618 Fixing the Great Wall
- Uva 11146 Insurrection(最短路+最小割)
- 记忆化搜索(跳舞机,uva 10618)
- 【暑假】[深入动态规划]UVa 10618 Fixing the Great Wall
- UVa 10618 跳舞机