【UVa-10618】 Tango Tango Insurrection


◇ 题目 +vjudge 链接+

(以下选自《算法竞赛入门经典》-刘汝佳,有删改)

<题目描述>

你想学着玩跳舞机。跳舞机的踏板上有4个箭头:上、下、下、右。当舞曲开始时,屏幕上会有一些箭头往上移动。当向上移动箭头与顶部的箭头模板重合时,你需要用脚踩一下踏板上的相同箭头。不需要踩箭头时,踩箭头并不会受到惩罚,但当需要踩箭头时,必须踩一下,哪怕已经有一只脚放在了该箭头上。很多舞曲的速度快,需要来回倒腾步子,所以最好写一个程序来帮助你选择一个轻松的踩踏方式,使得能量消耗最少。为了简单起见,将一个八分音符作为一个基本时间单位,每个时间单位要么需要踩一个箭头(不会同时需要踩两个箭头),要么什么都不需要踩。在任意时刻,你的左右脚应放在
不同的两个箭头上,且每个时间单位内只有一只脚能动(移动和/或踩箭头),不能跳跃。另外,你必须面朝前方以看到屏幕(即:你不能把左脚放到右箭头上,并且右脚放到左箭头上)。
当你执行一个动作(移动和/或踩)时,消耗的能量这样计算:

■ 如果这只脚上个时间单位没有任何动作,消耗1单位能量。
■ 如果这只脚上个时间单位没有移动,消耗3单位能量。
■ 如果这只脚上个时间单位移动到相邻箭头,消耗5单位能量。
■ 如果这只脚上个时间单位移动到相对箭头(上到下,或者左到右),消耗7单位能量。

正常情况下,你的左脚不能放到右箭头上(或者反之),但有一种情况例外:如果你的左脚在上箭头或者下箭头,你可以临时扭着身子用右脚踩左箭头,但是在你的右脚移出左箭头之前,你的左脚都不能移到另一个箭头上。类似地,右脚在上箭头或者下箭头时,你也可以临时用左脚踩右箭头。一开始,你的左脚在左箭头上,右脚在右箭头上。

<输入输出>

多组数据(不超过100组),每组数据包含一行——一个由'L','R','D','U'以及'.'组成的字符串(长度不超过70),第i个字符表示时间为i时需要踩下的键。

对于每组数据输出一个串,第i个字符表示时间为i时移动哪只脚,不移动输出'.'。


◇ 解析

由于本题影响答案的因素非常多,但是每一个因素的范围都不算大!所以我们选择DP,又因为本题不合法的条件也很多,我们选择记忆化搜索,能够简单地屏蔽所有不合法情况

首先给四个方向编号:上下左右依次编为0~3,空('.')编为4。方便计算、表示。顺便就把原来的字符串转换成int数组dir[]。

影响答案的因素如下:

  ■ 已经完成的箭头个数,设为pos,作为第一维状态;也就是说现在需要匹配第pos个箭头;

  ■ 当前左右脚分别所在的箭头编号,分别设为l,r,作为第二、三维状态;

  ■ 上一步是哪只脚移动/踩下,记为 pre,左脚操作为1,右脚为2,若没有移动/踩下,pre=0,作为第四维;

那么状态就像这样:dp[pos][l][r][pre]表示已经完成了前pos个箭头,且左右脚分别在l,r的位置,上一步左/右脚完成了一个箭头

很容易想到——初始的左右脚在左,右两键上,所以初始状态是 dp[0][2][3][0],即一个箭头都没有匹配,上一步没有操作。

而终止状态是当pos=n时(在这里数组从0开始)返回值为0。

在转移状态之前,我们还需要再处理几个函数,便于转移时值的计算:

  ■ 判断状态是否合法 bool Allowed(int l,int r,int fl,int fr)

参数表包含原来左右脚的位置l,r,以及下一步将要到达的位置fl,fr。

首先若左右脚都没有移动,则此时的状态是合法的,返回true。如果发现右脚没动(就是左脚动了)如果左脚将要到达的位置fl不是右脚的位置r,且右脚不在左箭头上(题目要求右脚只能临时在左箭头上,左脚也只能临时在右箭头上,所以如果右脚在左箭头上,是不能移动左脚的!),返回true。左脚与右脚判法相同。其余情况均为false。

■ 计算从当前位置到目标位置的花费 int Energy(int from,int to,inr last,int now)

参数表包含移动的脚的初始位置from和目标位置to,上一步进行操作的是哪只脚last,当前进行操作的是哪只脚now。

若当前进行操作的脚和上一次进行操作的脚不同,即last!=now时,根据题目第一条法则,我们可以判断这步操作花费为1。

若仅仅是没有移动,即from=to,则根据题目第二条法则,判断花费为3。

若移动的是相邻的两个箭头,判断花费为5。这里有一个小操作

最新文章

  1. 理解 OpenStack 高可用(HA)(1):OpenStack 高可用和灾备方案 [OpenStack HA and DR]
  2. 从H264码流中获取视频宽高 (SPS帧)
  3. freeradius 安装出错的解决办法
  4. jQuery演示10种不同的切换图片列表动画效果
  5. Silverlight 中datagrid控件-- 通过设置数据虚拟化加速显示
  6. 5、Linux下面桌面的安装
  7. React Native组件之Switch和Picker和Slide
  8. 2015安徽省赛 A.First Blood
  9. 关于协程的学习 &amp; 线程栈默认10M
  10. linux硬件时间修改与查看
  11. C# 之 user32函数库
  12. 沉金板VS 镀金板
  13. [置顶] iOS 应用程序内部国际化,不跟随系统语言
  14. jQuery中两种阻止事件冒泡的区别
  15. 使用babel转换es6编写的程序
  16. python笔记九(迭代)
  17. Vimtutor(中文版)学习笔记各章小结
  18. Chrome 插件安装技巧
  19. Tronado自定义Form组件
  20. 洛谷.3121.审查(AC自动机 链表)

热门文章

  1. Git常用配置
  2. JS获取元素属性、样式getComputedStyle()和currentStyle方法兼容性问题
  3. vlh 标签详解
  4. Redis入门--(二)Jedis的入门
  5. pm2的的常用命令及用法
  6. 22 Swap Nodes in Pairs
  7. *521. Longest Uncommon Subsequence I (bit manipulation 2^n)
  8. mmap内存映射
  9. 2019.03.15 ZJOI2019模拟赛 解题报告
  10. Codeforces Round #404 (Div. 2) ABC