UVA10618 多阶段DP
来源:互联网 发布:公积金贷款的软件 编辑:程序博客网 时间:2024/05/16 05:10
题意
跳舞机,需要按给出的方向序列踩箭头。一个箭头可以由左脚踩,也可以由右脚踩。正常情况下,不能出现左脚在右,右脚在左的情况。但是,可以出现,左脚在右,右脚在上或在下的情况,此时,在左脚移动前,右脚不能移动。当出现箭头时,即便你的脚在这个箭头上,也需要踩一下。如果这只脚上个时间单位没有任何动作,则消耗1单位能量。如果这只脚上个时间单位没有移动,则消耗3单位能量。如果这只脚上个时间单位移动到相邻箭头,消耗5单位能量。如果这只脚上个单位移动到相对箭头,消耗7单位能量。求如何踩所消耗的能量最少。
题解
多阶段DP。用dp[i][a][b][s]代表已经踩了i个箭头,左脚在a箭头上,右脚在b箭头上,上一个阶段移动的脚为s(0代表没有脚移动,1代表左脚移动,2代表右脚移动)。如果下一步是’.’则有三种决策方案,左脚移动到另一个箭头,右脚移动到另一个箭头,不移动。如果下一步是四个箭头之一,则有两种决策方案,左脚移动到该箭头,右脚移动到该箭头。
注意事项
本题条件判断比较多,特别要注意判断是否相等的等号(==)不要写成=。
代码
#include <iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;int dp[100][4][4][3];const int LEFT=1,RIGHT=2;char foot[]=".LR";char chc[256];struct Node{ int f,t;};Node action[100][4][4][3];int getAdd(int a,int b){ if(a==b) return 3; else if(a+b==3) return 7; else return 5;}int update(int i,int a,int b,int s,int t,int f,int &ta,int &tb){ ta=a,tb=b; if(f==LEFT){ ta=t; }else if(f==RIGHT){ tb=t; } if(ta==tb){ return -1; }else if(ta==RIGHT&&tb==LEFT){ return -1; }else if(b==LEFT&&ta!=a){ return -1; }else if(a==RIGHT&&tb!=b){ return -1; } if(f==0){ return 0; }else if(f!=s){ return 1; }else{ if(f==LEFT){ return getAdd(a,ta); }else{ return getAdd(b,tb); } }}void energy(int i,int a,int b,int s,int t,int f){ int ta,tb; int v=update(i,a,b,s,t,f,ta,tb); if(v<0) return ; int& ans=dp[i][a][b][s]; if(ans>v+dp[i+1][ta][tb][f]){ ans=v+dp[i+1][ta][tb][f]; action[i][a][b][s]=(Node){f,t}; }}int main(){ //freopen("d://input.txt","r",stdin); //freopen("d://output.txt","w",stdout); char ch[105]; chc['U']=0,chc['L']=1,chc['R']=2,chc['D']=3; while(scanf("%s",ch)){ if(ch[0]=='#') break; int n=strlen(ch); memset(dp,0,sizeof(dp)); for(int i=n-1;i>=0;i--){ for(int a=0;a<4;a++){ for(int b=0;b<4;b++){ if(a!=b){ for(int s=0;s<3;s++){ dp[i][a][b][s]=n*10; if(ch[i]=='.'){ energy(i,a,b,s,0,0); for(int k=0;k<4;k++){ energy(i,a,b,s,k,LEFT); energy(i,a,b,s,k,RIGHT); } }else{ energy(i,a,b,s,chc[ch[i]],LEFT); energy(i,a,b,s,chc[ch[i]],RIGHT); } } } } } } int a=LEFT,b=RIGHT,s=0; for(int i=0;i<n;i++){ int f=action[i][a][b][s].f; printf("%c",foot[f]); int t=action[i][a][b][s].t; s=f; if(f==LEFT){ a=t; }else if(f==RIGHT){ b=t; } } printf("\n"); } return 0;}
0 0
- UVA10618 多阶段DP
- UVa10618
- UVA10618 & POJ1726 & ZOJ2120 - Tango Tango Insurrection(比较烦的DP)
- UVA116 简单的多阶段DP
- UVa10618 Tango Tango Insurrection
- CF-18E - Flag 2(DP多阶段决策)
- hdu 1224 Free DIY Tour(DP多阶段决策)
- UVA 116 Unidirectional TSP (多阶段决策问题,DP解决)
- hdu 2059 龟兔赛跑【DP中多阶段决策的典型例题】
- HDU 2059 龟兔赛跑(DP和多阶段策略问题,基础题)
- UESTC 2016 Summer Training #2 Div.2 A dp、递推、多阶段问题
- UVa357 Let Me Count The Ways DP多阶段决策问题
- UVA 12563 Jin Ge Jin Qu hao(多阶段决策问题,DP)
- NGINX多阶段处理
- 阶段
- 阶段
- 最近学习dp的阶段小结(一)
- [背包问题][第三阶段-初见dp][HDU-2504]Bone Collector
- PAT A1013. Battle Over Cities (25)
- RCNN系列学习笔记(1):Rich feature hierarchies for accurate object detection and semantic segmentation
- 尚观嵌入式c语言编程进阶笔记——3.指针
- 构造函数与析构函数
- NZT激活码
- UVA10618 多阶段DP
- 文件操作命令http://blog.csdn.net/hsd2012/article/details/45170817
- Android中解析xml
- DBN/DNN/ANN/SNN
- 从0到1学习node(七)之express搭建简易论坛
- Leetcode 322. Coin Change
- Reactive Programming with RxJava-Chapter3:Operators and Transformations(2)
- lstm
- 子类调用父类构造器时的Java类成员初始化顺序